home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / Xpm / pixmap / Pixmap.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  77KB  |  2,710 lines

  1. /* * Last edited: Jan  2 10:59 1992 (mallet) */
  2. /*
  3.  * $Id: Pixmap.c,v 1.10 1992/10/27 08:37:11 mallet Exp $
  4.  * 
  5.  * Copyright 1991 Lionel Mallet
  6.  * 
  7.  * Permission to use, copy, modify, distribute, and sell this software and its
  8.  * documentation for any purpose is hereby granted without fee, provided that
  9.  * the above copyright notice appears in all copies and that both that
  10.  * copyright notice and this permission notice appear in supporting
  11.  * documentation, and that the name of Lionel MALLET not be used in
  12.  * advertising or publicity pertaining to distribution of the software
  13.  * without specific, written prior permission.  Lionel MALLET makes no
  14.  * representations about the suitability of this software for any
  15.  * purpose.  It is provided "as is" without express or implied warranty.
  16.  *
  17.  * Lionel MALLET DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  18.  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  19.  * FITNESS, IN NO EVENT SHALL Lionel MALLET BE LIABLE FOR ANY SPECIAL,
  20.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  21.  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 
  22.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  23.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  24.  *
  25.  *  This software is opened and free. Furthermore, everybody is kindly
  26.  * invited to participate to improve it for the benefit of all.
  27.  * Improvements can be new features, bugs fixes and porting issues
  28.  * resolution.
  29.  *
  30.  * Author:  Lionel Mallet, SIMULOG
  31.  */
  32.  
  33. /*
  34.  * $XConsortium: Pixmap.c,v 1.12 90/06/09 20:19:28 dmatic Exp $
  35.  *
  36.  * Copyright 1989 Massachusetts Institute of Technology
  37.  *
  38.  * Permission to use, copy, modify, distribute, and sell this software and its
  39.  * documentation for any purpose is hereby granted without fee, provided that
  40.  * the above copyright notice appear in all copies and that both that
  41.  * copyright notice and this permission notice appear in supporting
  42.  * documentation, and that the name of M.I.T. not be used in advertising or
  43.  * publicity pertaining to distribution of the software without specific,
  44.  * written prior permission.  M.I.T. makes no representations about the
  45.  * suitability of this software for any purpose.  It is provided "as is"
  46.  * without express or implied warranty.
  47.  *
  48.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  49.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  50.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  51.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  52.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  53.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  54.  *
  55.  * Author:  Davor Matic, MIT X Consortium
  56.  */
  57.  
  58. static char rcsid[] = "$Id: Pixmap.c,v 1.10 1992/10/27 08:37:11 mallet Exp $";
  59.  
  60. #include <X11/IntrinsicP.h>
  61. #include <X11/Xmu/Converters.h>
  62. #include <X11/StringDefs.h>
  63. #include <X11/Xatom.h>
  64. #include <X11/Xos.h>
  65. #include <X11/cursorfont.h>
  66. #include "PixmapP.h"
  67.     
  68. #include <stdio.h>
  69. #include <math.h>
  70.  
  71. #define XtStrlen(s)                   ((s) ? strlen(s) : 0)
  72. #define abs(x)                        (((x) > 0) ? (x) : -(x))
  73. #define min(x, y)                     (((x) < (y)) ? (x) : (y))
  74. #define max(x, y)                     (((x) > (y)) ? (x) : (y))
  75.  
  76.  
  77. static Boolean _PWDEBUG = False;
  78. static unsigned int depth;
  79. static int screen;
  80. static Display *dpy;
  81.  
  82. #define DefaultGridTolerance 5
  83. #define DefaultPixmapWidth   32
  84. #define DefaultPixmapHeight  32
  85. #define DefaultStippled      TRUE
  86. #define DefaultGrid          TRUE
  87. #define DefaultResize        TRUE
  88. #define DefaultProportional  TRUE
  89. #define DefaultAxes          FALSE
  90. #define DefaultDistance      10
  91. #define DefaultSquareSize    20
  92.  
  93. static XtResource resources[] = {
  94. #define offset(field) XtOffset(PixmapWidget, pixmap.field)
  95. {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
  96.    offset(cursor), XtRString, "tcross"},
  97. {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
  98.      offset(foreground_pixel), XtRString, XtDefaultForeground},
  99. {XtNhighlight, XtCHighlight, XtRPixel, sizeof(Pixel),
  100.      offset(highlight_pixel), XtRString, XtDefaultForeground},
  101. {XtNframing, XtCFraming, XtRPixel, sizeof(Pixel),
  102.      offset(framing_pixel), XtRString, XtDefaultForeground},
  103. {XtNtransparent, XtCTransparent, XtRPixel, sizeof(Pixel),
  104.      offset(transparent_pixel), XtRString, XtDefaultTransparent},
  105. {XtNproportional, XtCProportional, XtRBoolean, sizeof(Boolean),
  106.      offset(proportional), XtRImmediate, (XtPointer) DefaultProportional},
  107. {XtNgrid, XtCGrid, XtRBoolean, sizeof(Boolean),
  108.      offset(grid), XtRImmediate, (XtPointer) DefaultGrid},
  109. {XtNgridTolerance, XtCGridTolerance, XtRDimension, sizeof(Dimension),
  110.      offset(grid_tolerance), XtRImmediate, (XtPointer) DefaultGridTolerance},
  111. {XtNstippled, XtCStippled, XtRBoolean, sizeof(Boolean),
  112.      offset(stippled), XtRImmediate, (XtPointer) DefaultStippled},
  113. {XtNaxes, XtCAxes, XtRBoolean, sizeof(Boolean),
  114.      offset(axes), XtRImmediate, (XtPointer) DefaultAxes},
  115. {XtNresize, XtCResize, XtRBoolean, sizeof(Boolean),
  116.      offset(resize), XtRImmediate, (XtPointer) DefaultResize},
  117. {XtNdistance, XtCDistance, XtRDimension, sizeof(Dimension),
  118.      offset(distance), XtRImmediate, (XtPointer) DefaultDistance},
  119. {XtNsquareSize, XtCSquareSize, XtRDimension, sizeof(Dimension),
  120.      offset(squareH), XtRImmediate, (XtPointer) DefaultSquareSize},
  121. {XtNsquareSize, XtCSquareSize, XtRDimension, sizeof(Dimension),
  122.      offset(squareW), XtRImmediate, (XtPointer) DefaultSquareSize},
  123. {XtNpixmapWidth, XtCPixmapWidth, XtRDimension, sizeof(Dimension),
  124.      offset(width), XtRImmediate, (XtPointer) DefaultPixmapWidth},
  125. {XtNpixmapHeight, XtCPixmapHeight, XtRDimension, sizeof(Dimension),
  126.      offset(height), XtRImmediate, (XtPointer) DefaultPixmapHeight},
  127. {XtNbutton1Action, XtCButton1Action, XtRInt, sizeof(int),
  128.      offset(button_action[0]), XtRImmediate, (XtPointer) Set},
  129. {XtNbutton2Action, XtCButton2Action, XtRInt, sizeof(int),
  130.      offset(button_action[1]), XtRImmediate, (XtPointer) Invert},
  131. {XtNbutton3Action, XtCButton3Action, XtRInt, sizeof(int),
  132.      offset(button_action[2]), XtRImmediate, (XtPointer) Clear},
  133. {XtNbutton4Action, XtCButton4Action, XtRInt, sizeof(int),
  134.      offset(button_action[3]), XtRImmediate, (XtPointer) Clear},
  135. {XtNbutton5Action, XtCButton5Action, XtRInt, sizeof(int),
  136.      offset(button_action[4]), XtRImmediate, (XtPointer) Clear},
  137. {XtNfilename, XtCFilename, XtRString, sizeof(String),
  138.      offset(filename), XtRImmediate, (XtPointer) XtNscratch},
  139. {XtNaddColorNtfyProc, XtCAddColorNtfyProc, XtRFunction, sizeof(AddColorNotifyProc), offset(AddColorNotify), XtRImmediate, (XtPointer) NULL},
  140. {XtNextensionNtfyProc, XtCExtensionNtfyProc, XtRFunction, sizeof(ExtensionNotifyProc), offset(extensionNotify), XtRImmediate, (XtPointer) NULL},
  141. {XtNstipple, XtCStipple, XtRBitmap, sizeof(Pixmap),
  142.      offset(stipple), XtRImmediate, (XtPointer) XtUnspecifiedPixmap},
  143. #undef offset
  144. };
  145.  
  146. void PWTMark();
  147. void PWTUnmark();
  148. void PWTPaste();
  149. void PWTSetColor();
  150.  
  151. static XtActionsRec actions[] =
  152. {
  153. {"mark",               (XtActionProc)PWTMark},
  154. {"unmark",             (XtActionProc)PWTUnmark},
  155. {"paste",              (XtActionProc)PWTPaste},
  156. {"set-color",          (XtActionProc)PWTSetColor},
  157. {"PW-debug",           (XtActionProc)PWDebug},
  158. {"terminate",          (XtActionProc)PWTerminate},
  159. {"store-to-buffer",    (XtActionProc)PWStoreToBuffer},
  160. {"change-notify",      (XtActionProc)PWChangeNotify},
  161. {"set-changed",        (XtActionProc)PWSetChanged},
  162. {"up",                 (XtActionProc)PWUp},
  163. {"down",               (XtActionProc)PWDown},
  164. {"left",               (XtActionProc)PWLeft},
  165. {"right",              (XtActionProc)PWRight},
  166. {"fold",               (XtActionProc)PWFold},
  167. {"flip-horiz",         (XtActionProc)PWFlipHoriz},
  168. {"flip-vert",          (XtActionProc)PWFlipVert},
  169. {"rotate-right",       (XtActionProc)PWRotateRight},
  170. {"rotate-left",        (XtActionProc)PWRotateLeft},
  171. {"set",                (XtActionProc)PWSet},
  172. {"clear",              (XtActionProc)PWClear},
  173. {"undo",               (XtActionProc)PWUndo},
  174. {"redraw",             (XtActionProc)PWRedraw},
  175. };
  176.  
  177. static char translations[] =
  178. "\
  179.  Ctrl<Btn1Down>:   mark()\n\
  180.  Ctrl<Btn2Down>:   paste()\n\
  181.  Ctrl<Btn3Down>:   unmark()\n\
  182.  Shift<BtnUp>:    set-color()\n\
  183.  Ctrl<Key>l:       redraw()\n\
  184.  <Key>d:           PW-debug()\n\
  185.  <Key>t:           terminate()\n\
  186.  <Key>Up:          store-to-buffer()\
  187.                    up()\
  188.                    change-notify()\
  189.                    set-changed()\n\
  190.  <Key>Down:        store-to-buffer()\
  191.                    down()\
  192.                    change-notify()\
  193.                    set-changed()\n\
  194.  <Key>Left:        store-to-buffer()\
  195.                    left()\
  196.                    change-notify()\
  197.                    set-changed()\n\
  198.  <Key>Right:       store-to-buffer()\
  199.                    right()\
  200.                    change-notify()\
  201.                    set-changed()\n\
  202.  <Key>f:           store-to-buffer()\
  203.                    fold()\
  204.                    change-notify()\
  205.                    set-changed()\n\
  206.  <Key>h:           store-to-buffer()\
  207.                    flip-horiz()\
  208.                    change-notify()\
  209.                    set-changed()\n\
  210.  <Key>v:           store-to-buffer()\
  211.                    flip-vert()\
  212.                    change-notify()\
  213.                    set-changed()\n\
  214.  <Key>r:           store-to-buffer()\
  215.                    rotate-right()\
  216.                    change-notify()\
  217.                    set-changed()\n\
  218.  <Key>l:           store-to-buffer()\
  219.                    rotate-left()\
  220.                    change-notify()\
  221.                    set-changed()\n\
  222.  <Key>s:           store-to-buffer()\
  223.                    set()\
  224.                    change-notify()\
  225.                    set-changed()\n\
  226.  <Key>c:           store-to-buffer()\
  227.                    clear()\
  228.                    change-notify()\
  229.                    set-changed()\n\
  230.  <Key>u:           undo()\
  231.                    change-notify()\
  232.                    set-changed()\n\
  233. ";
  234.  
  235. Atom targets[] = {
  236.     XA_BITMAP,
  237.     XA_PIXMAP,
  238.     XA_STRING,
  239. };
  240.  
  241. #include "Requests.h"
  242.  
  243. static void ClassInitialize();
  244. static void Initialize();
  245. static void Redisplay();
  246. static void Resize();
  247. static void InternalResize();
  248. static void Destroy();
  249. static Boolean SetValues();
  250.  
  251. PixmapClassRec pixmapClassRec = {
  252. {   /* core fields */
  253.     /* superclass        */    (WidgetClass) &coreClassRec,
  254.     /* class_name        */    "Pixmap",
  255.     /* widget_size        */    sizeof(PixmapRec),
  256.     /* class_initialize        */    ClassInitialize,
  257.     /* class_part_initialize    */    NULL,
  258.     /* class_inited        */    FALSE,
  259.     /* initialize        */    Initialize,
  260.     /* initialize_hook        */    NULL,
  261.     /* realize            */    XtInheritRealize,
  262.     /* actions            */    actions,
  263.     /* num_actions        */    XtNumber(actions),
  264.     /* resources        */    resources,
  265.     /* num_resources        */    XtNumber(resources),
  266.     /* xrm_class        */    NULLQUARK,
  267.     /* compress_motion        */    TRUE,
  268.     /* compress_exposure    */    FALSE,
  269.     /* compress_enterleave    */    TRUE,
  270.     /* visible_interest        */    TRUE,
  271.     /* destroy            */    Destroy,
  272.     /* resize            */    Resize,
  273.     /* expose            */    Redisplay,
  274.     /* set_values        */    SetValues,
  275.     /* set_values_hook        */    NULL,
  276.     /* set_values_almost    */    XtInheritSetValuesAlmost,
  277.     /* get_values_hook        */    NULL,
  278.     /* accept_focus        */    NULL,
  279.     /* version            */    XtVersion,
  280.     /* callback_private        */    NULL,
  281.     /* tm_table            */    translations,
  282.     /* query_geometry        */    XtInheritQueryGeometry,
  283.     /* display_accelerator    */    XtInheritDisplayAccelerator,
  284.     /* extension        */    NULL,
  285.   },
  286.   {
  287.     /* targets                  */      targets,
  288.     /* num_trets                */      XtNumber(targets),
  289.     /* requests                 */      requests,
  290.     /* num_requests             */      XtNumber(requests),
  291.   }
  292. };
  293.  
  294. WidgetClass pixmapWidgetClass = (WidgetClass) &pixmapClassRec;
  295.  
  296. #if NeedFunctionPrototypes
  297. Boolean PWQueryGrid(Widget w)
  298. #else
  299. Boolean PWQueryGrid(w)
  300.     Widget w;
  301. #endif
  302. {
  303.     PixmapWidget PW = (PixmapWidget) w;
  304.  
  305.     return PW->pixmap.grid;
  306. }
  307.  
  308. #if NeedFunctionPrototypes
  309. Boolean PWQueryAxes(Widget w)
  310. #else
  311. Boolean PWQueryAxes(w)
  312.     Widget w;
  313. #endif
  314. {
  315.     PixmapWidget PW = (PixmapWidget) w;
  316.  
  317.     return PW->pixmap.axes;
  318. }
  319.  
  320. #if NeedFunctionPrototypes
  321. Boolean PWQueryStored(Widget w)
  322. #else
  323. Boolean PWQueryStored(w)
  324.     Widget w;
  325. #endif
  326. {
  327.     PixmapWidget PW = (PixmapWidget) w;
  328.     
  329.     return (PW->pixmap.storage != NULL);
  330. }
  331.  
  332.  
  333. #if NeedFunctionPrototypes
  334. Pixel PWGetTransparentPixel(Widget w)
  335. #else
  336. Pixel PWGetTransparentPixel(w)
  337.     Widget w;
  338. #endif
  339. {
  340.     PixmapWidget PW = (PixmapWidget) w;
  341.     
  342.     return PW->pixmap.transparent_pixel;
  343. }
  344.  
  345. #if NeedFunctionPrototypes
  346. Pixmap PWGetStipplePixmap(Widget w)
  347. #else
  348. Pixmap PWGetStipplePixmap(w)
  349.     Widget w;
  350. #endif
  351. {
  352.     PixmapWidget PW = (PixmapWidget) w;
  353.  
  354.     if (PW->pixmap.stippled) return PW->pixmap.stipple;
  355.     else return XtUnspecifiedPixmap;
  356. }
  357.  
  358. #include "Extensions.c"
  359. #include "Graphics.c"
  360. #include "Handlers.c"
  361. #include "ReqMach.c"
  362. #include "CutAndPaste.c"
  363.  
  364. #if NeedFunctionPrototypes
  365. void PWDebug(Widget w)
  366. #else
  367. void PWDebug(w)
  368.     Widget w;
  369. #endif
  370. {
  371.      _PWDEBUG ^= True;
  372.      XSynchronize(dpy, _PWDEBUG);
  373. }
  374.  
  375. void PWTSetColor(w, event)
  376.      Widget w;
  377.      XEvent *event;
  378. {
  379.   PixmapWidget PW = (PixmapWidget) w;
  380.   
  381.   PWSetForeground(w, 
  382.           PWGetPxl(w, InPixmapX(PW, event->xbutton.x), 
  383.                InPixmapY(PW, event->xbutton.y)));
  384.   if (PW->pixmap.colorNotify)
  385.     (*PW->pixmap.colorNotify)(w, PW->pixmap.foreground_pixel);
  386. }
  387.  
  388. #if NeedFunctionPrototypes
  389. void ColorNotify(Widget w, UseColorNotifyProc proc)
  390. #else
  391. void ColorNotify(w, proc)
  392.      Widget w;
  393.      UseColorNotifyProc proc;
  394. #endif
  395. {
  396.   PixmapWidget PW = (PixmapWidget) w;
  397.   
  398.   PW->pixmap.colorNotify = proc;
  399. }
  400.  
  401. #if NeedFunctionPrototypes
  402. void ExtensionNotify(Widget w, ExtensionNotifyProc proc)
  403. #else
  404. void ExtensionNotify (w, proc)
  405.      Widget                     w;
  406.      ExtensionNotifyProc        proc;
  407. #endif
  408. {
  409.   PixmapWidget PW = (PixmapWidget) w;
  410.  
  411.   PW->pixmap.extensionNotify = proc;
  412. }
  413.  
  414. #if NeedFunctionPrototypes
  415. void PWPickPixelDraw(Widget w, Position x, Position y, int value)
  416. #else
  417. void PWPickPixelDraw(w, x, y, value)
  418.     Widget   w;
  419.     Position x; 
  420.     Position y;
  421.     int      value;
  422. #endif
  423. {
  424.     PixmapWidget PW = (PixmapWidget) w;
  425.  
  426.     if (PW->pixmap.pickPixelDraw) 
  427.       (*PW->pixmap.pickPixelDraw)(w, x, y, value);
  428. }
  429.  
  430.  
  431. #if NeedFunctionPrototypes
  432. void PWPickPixelComplete(Widget w, Position x, Position y, int value)
  433. #else
  434. void PWPickPixelComplete(w, x, y, value)
  435.     Widget   w;
  436.     Position x; 
  437.     Position y;
  438.     int      value;
  439. #endif
  440. {
  441.     PixmapWidget PW = (PixmapWidget) w;
  442.  
  443.     if (PW->pixmap.pickPixelComplete) 
  444.       (*PW->pixmap.pickPixelComplete)(w, x, y, value);
  445. }
  446.  
  447.  
  448. Pixmap GetPixmap(PW, image)
  449.      PixmapWidget PW;
  450.      XImage *image;
  451. {
  452.   Pixmap pix;
  453.   XGCValues gcv;
  454.   GC gc ;
  455.   
  456.   pix = XCreatePixmap(dpy, XtWindow((Widget) PW),
  457.               image->width, image->height, image->depth);
  458.   gcv.function = GXcopy;
  459.   gc = XCreateGC(dpy, pix, GCFunction, &gcv);
  460.   
  461.   XPutImage(dpy, pix, gc, image, 0, 0, 0, 0,
  462.         image->width, image->height);
  463.   return(pix);
  464. }
  465.   
  466. XImage *GetImage(PW, pixmap)
  467.     PixmapWidget PW;
  468.     Pixmap pixmap;
  469. {
  470.     Window root;
  471.     int x, y;
  472.     unsigned int width, height, border_width, depth;
  473.     XImage *image;
  474.  
  475.     XGetGeometry(dpy, pixmap, &root, &x, &y,
  476.          &width, &height, &border_width, &depth);
  477.  
  478.     image = XGetImage(dpy, pixmap, x, y, width, height,
  479.               AllPlanes, ZPixmap);
  480.  
  481.     return image;
  482. }
  483.  
  484. XImage *CreateMaskImage(PW, width, height)
  485.     PixmapWidget PW;
  486.     Dimension width, height;
  487. {
  488.   Position x, y;
  489.   int bitmap_pad;
  490.   XImage *mask_image;
  491.  
  492.   mask_image = XCreateImage(dpy, DefaultVisual(dpy, screen), 1, ZPixmap, 0, 
  493.                 NULL, width, height, 8, 0);
  494.   if (!mask_image) 
  495.   {
  496.       XtAppWarning(XtWidgetToApplicationContext((Widget) PW),
  497.            "Pixmap error in creating XImage\n");
  498.       exit(1);
  499.   }
  500.   else mask_image->data = XtCalloc(1,
  501.                    mask_image->bytes_per_line *
  502.                      mask_image->height);
  503.  
  504.   /* Initialize all pixels to 1: default mask is rectangular */ 
  505.   XAddPixel(mask_image, 1);
  506.   
  507.   return mask_image;
  508. }
  509.  
  510. XImage *CreatePixmapImage(PW, width, height)
  511.     PixmapWidget PW;
  512.     Dimension width, height;
  513. {
  514.   Position x, y;
  515.   int bitmap_pad;
  516.   XImage *image;
  517.  
  518.   if (depth <= 8) bitmap_pad = 8;
  519.   else if (depth <= 16) bitmap_pad = 16;
  520.   else bitmap_pad = 32;
  521.   
  522.   image = XCreateImage(dpy,
  523.                DefaultVisual(dpy, screen),
  524.                depth,
  525.                ZPixmap, 0,
  526.                NULL, width, height,
  527.                bitmap_pad, 0);
  528.  
  529.   if (!image) 
  530.     {
  531.       XtAppWarning(XtWidgetToApplicationContext((Widget) PW),
  532.            "Pixmap error in creating XImage\n");
  533.       exit(1);
  534.     }
  535.   else image->data = XtCalloc(1, image->bytes_per_line * height);
  536.   
  537.   if (WhitePixel(dpy, screen) != 0) /* to clear the image, hope white is or 0 
  538.                        or greater then black */
  539.     XAddPixel(image, WhitePixel(dpy, screen)); /* because image pixels are 
  540.                           initialized to 0 */
  541.   
  542.   if (_PWDEBUG) {
  543.     printf("bytes_per_line %d\n", image->bytes_per_line);
  544.     printf("size data %d\n", image->bytes_per_line * height);
  545.     printf("bitmap pad %d\n", image->bitmap_pad);
  546.   }
  547.      
  548.   return image;
  549. }
  550.  
  551. void DestroyPixmapImage(image)
  552.     XImage **image;
  553. {
  554.     if (*image) 
  555.       {
  556.     XDestroyImage(*image);
  557.     *image = NULL;
  558.       }
  559. }
  560.  
  561. #if NeedFunctionPrototypes
  562. XImage *PWGetImage(Widget w)
  563. #else
  564. XImage *PWGetImage(w)
  565.     Widget w;
  566. #endif
  567. {
  568.     PixmapWidget PW = (PixmapWidget) w;
  569.  
  570.     return PW->pixmap.image;
  571. }
  572.  
  573. #if NeedFunctionPrototypes
  574. void PWChangeNotify(Widget w, XtPointer client_data, XtPointer call_data)
  575. #else
  576. void PWChangeNotify(w, client_data, call_data)
  577.      Widget       w;
  578.      XtPointer      client_data;
  579.      XtPointer      call_data;
  580. #endif
  581. {
  582.     PixmapWidget PW = (PixmapWidget) w;
  583.  
  584.     if (PW->pixmap.notify)
  585.     (*PW->pixmap.notify)(w, client_data, call_data);
  586. }
  587.  
  588. #if NeedFunctionPrototypes
  589. void Notify(Widget w, void (*proc)())
  590. #else
  591. void Notify(w, proc)
  592.      Widget   w;
  593.      void   (*proc)();
  594. #endif
  595. {
  596.     PixmapWidget PW = (PixmapWidget) w;
  597.  
  598.     PW->pixmap.notify = proc;
  599. }
  600.  
  601. #if NeedFunctionPrototypes
  602. void PWSetChanged(Widget w)
  603. #else
  604. void PWSetChanged(w)
  605.     Widget w;
  606. #endif
  607. {
  608.     PixmapWidget PW = (PixmapWidget) w;
  609.     
  610.     PW->pixmap.changed = True;
  611. }
  612.  
  613. #if NeedFunctionPrototypes
  614. Boolean PWQueryChanged(Widget w)
  615. #else
  616. Boolean PWQueryChanged(w)
  617.     Widget w;
  618. #endif
  619. {
  620.     PixmapWidget PW = (PixmapWidget) w;
  621.     
  622.     return PW->pixmap.changed;
  623. }
  624.  
  625. #if NeedFunctionPrototypes
  626. void PWClearChanged(Widget w)
  627. #else
  628. void PWClearChanged(w)
  629.     Widget w;
  630. #endif
  631. {
  632.     PixmapWidget PW = (PixmapWidget) w;
  633.     
  634.     PW->pixmap.changed = False;
  635. }
  636.  
  637. #if NeedFunctionPrototypes
  638. void PWSelect(Widget w, Position from_x, Position from_y, 
  639.           Position to_x, Position to_y, Time time)
  640. #else
  641. void PWSelect(w, from_x, from_y, to_x, to_y, time)
  642.     Widget w;
  643.     Position from_x, from_y, to_x, to_y;
  644.     Time time;
  645. #endif
  646. {
  647.     PWMark(w, from_x, from_y, to_x, to_y);
  648.     PWGrabSelection(w, time);
  649. }
  650.  
  651. #if NeedFunctionPrototypes
  652. void PWSwitchAxes(Widget w)
  653. #else
  654. void PWSwitchAxes(w)
  655.      Widget w;
  656. #endif
  657. {
  658.     PixmapWidget PW = (PixmapWidget) w;
  659.  
  660.     PW->pixmap.axes ^= True;
  661.     PWHighlightAxes(w);
  662. }
  663.  
  664. #if NeedFunctionPrototypes
  665. void PWAxes(Widget w, Boolean _switch)
  666. #else
  667. void PWAxes(w, _switch)
  668.     Widget w;
  669.     Boolean _switch;
  670. #endif
  671. {
  672.     PixmapWidget PW = (PixmapWidget) w;
  673.     
  674.     if (PW->pixmap.axes != _switch)
  675.     PWSwitchAxes(w);
  676. }
  677.  
  678. #if NeedFunctionPrototypes
  679. void PWRedrawAxes(Widget w)
  680. #else
  681. void PWRedrawAxes(w)
  682.     Widget w;
  683. #endif
  684. {
  685.     PixmapWidget PW = (PixmapWidget) w;
  686.     
  687.     if (PW->pixmap.axes)
  688.     PWHighlightAxes(w);
  689. }
  690.  
  691. #if NeedFunctionPrototypes
  692. void PWPutImage(Widget w, Display *display, Drawable drawable, GC gc, 
  693.         Position x, Position y)
  694. #else
  695. void PWPutImage(w, display, drawable, gc, x, y)
  696.      PixmapWidget w;
  697.      Display     *display;
  698.      Drawable     drawable;
  699.      GC           gc;
  700.      Position     x, y;
  701. #endif
  702. {
  703.     PixmapWidget PW = (PixmapWidget) w;
  704.  
  705.   XPutImage(display, drawable, gc, PW->pixmap.image,
  706.         0, 0, x, y, PW->pixmap.image->width, PW->pixmap.image->height);
  707. }
  708.  
  709.  
  710. String StripFilename(filename)
  711.     String filename;
  712. {
  713.     char *begin = rindex (filename, '/');
  714.     char *end, *result;
  715.     int length;
  716.     
  717.     if (filename) {
  718.     begin = (begin ? begin + 1 : filename);
  719.     end = index (begin, '.'); /* change to rindex to allow longer names */
  720.     length = (end ? (end - begin) : strlen (begin));
  721.     result = (char *) XtMalloc (length + 1);
  722.     strncpy (result, begin, length);
  723.     result [length] = '\0';
  724.     return (result);
  725.     }
  726.     else
  727.     return (XtNdummy);
  728. }
  729.  
  730.  
  731. void SetTransparentPixels(pw, image, mask_image)
  732.      PixmapWidget pw;
  733.      XImage *image, *mask_image;
  734. {
  735.     register Position x, y;
  736.     
  737.   for (x = 0; x < image->width; x++)
  738.     for (y = 0; y < image->height; y++)
  739.       if (XGetPixel(mask_image, x, y) == 0)
  740.     XPutPixel(image, x, y, pw->pixmap.transparent_pixel);
  741. }
  742.  
  743.  
  744. char *ReadColorsInUse(image, mask_image, attribs)
  745.      XImage *image;
  746.      XpmAttributes *attribs;
  747. {
  748.   /* Used array is mallocd'ed here and should therefore be freed by caller */
  749.   char *Used = (char *)XtCalloc(1<<depth, sizeof(char)); /* without transp. */
  750.   register Position x, y;
  751.   register Pixel pxl;
  752.  
  753.   for (x = 0; x < image->width; x++)
  754.     for (y = 0; y < image->height; y++)
  755.     {
  756.     pxl = GetPxlFromImageAndMask(image, mask_image, x, y);
  757.     if (pxl == TRANSPARENT(dpy, screen))
  758.     {
  759.         if (!attribs->mask_pixel) {
  760.         attribs->mask_pixel = 1;
  761.         attribs->ncolors++;
  762.         }
  763.     }
  764.     else if (!Used[pxl])
  765.     {
  766.         Used[pxl]++;
  767.         attribs->ncolors++;
  768.     }
  769.     }
  770.  
  771.   return Used;
  772. }
  773.     
  774. void InitializeXpmAttributes(attribs)
  775.      XpmAttributes *attribs;
  776. {
  777.     attribs->visual = (Visual *)0;
  778.     attribs->colormap = (Colormap)0;
  779.     attribs->depth = 0;
  780.     attribs->width = 0;
  781.     attribs->height = 0;
  782.     attribs->x_hotspot = 0;
  783.     attribs->y_hotspot = 0;
  784.     attribs->cpp = 0;
  785.     attribs->pixels = (Pixel *)0;
  786.     attribs->npixels = 0;
  787.     attribs->colorsymbols = (XpmColorSymbol *)0;
  788.     attribs->numsymbols = 0;
  789.     attribs->rgb_fname = NULL;
  790.     attribs->nextensions = 0;
  791.     attribs->extensions = (XpmExtension *)0;
  792.     attribs->ncolors = 0;
  793.     attribs->colorTable = NULL;
  794.     attribs->hints_cmt = NULL;
  795.     attribs->colors_cmt = NULL;
  796.     attribs->pixels_cmt = NULL;
  797.     attribs->mask_pixel = 0;
  798. }
  799.  
  800.  
  801. #if NeedFunctionPrototypes
  802. void PWGetUnzoomedPixmap(Widget w, Pixmap *pixmap, Pixmap *pixmap_mask)
  803. #else
  804. void PWGetUnzoomedPixmap(w, pixmap, pixmap_mask)
  805.      Widget w;
  806.      Pixmap *pixmap, *pixmap_mask;
  807. #endif
  808. {
  809.     PixmapWidget PW = (PixmapWidget) w;
  810.     XImage *mask_image, *image;
  811.     
  812.     if (PW->pixmap.zooming) 
  813.       {    
  814.     image = CreatePixmapImage(PW,
  815.                   (Dimension) PW->pixmap.zoom.image->width,
  816.                   (Dimension) PW->pixmap.zoom.image->height);
  817.     CopyImageData(PW->pixmap.zoom.image, image, 0, 0, 
  818.               (Dimension) PW->pixmap.zoom.image->width,
  819.               (Dimension) PW->pixmap.zoom.image->height, 0, 0);
  820.     CopyImageData(PW->pixmap.image, image, 
  821.               0, 0, 
  822.               PW->pixmap.image->width - 1,
  823.               PW->pixmap.image->height - 1,
  824.               PW->pixmap.zoom.at_x, PW->pixmap.zoom.at_y);
  825.  
  826.     mask_image = CreateMaskImage(PW,
  827.                      (Dimension)PW->pixmap.zoom.image->width,
  828.                      (Dimension)PW->pixmap.zoom.image->height);
  829.     CopyImageData(PW->pixmap.zoom.mask_image, mask_image, 0, 0, 
  830.               (Dimension) PW->pixmap.zoom.mask_image->width,
  831.               (Dimension) PW->pixmap.zoom.mask_image->height, 0, 0);
  832.     CopyImageData(PW->pixmap.mask_image, mask_image, 
  833.               0, 0, 
  834.               PW->pixmap.mask_image->width - 1,
  835.               PW->pixmap.mask_image->height - 1,
  836.               PW->pixmap.zoom.at_x, PW->pixmap.zoom.at_y);
  837.     
  838.       }
  839.     else
  840.       {
  841.       image = PW->pixmap.image;
  842.       mask_image = PW->pixmap.mask_image;
  843.       }
  844.  
  845.     
  846.     *pixmap = GetPixmap(PW, image);
  847.     *pixmap_mask = GetPixmap(PW, mask_image);
  848.  
  849.     if (PW->pixmap.zooming) {
  850.     DestroyPixmapImage(&image);
  851.     DestroyMaskImage(&mask_image);
  852.     }
  853. }
  854.  
  855.  
  856. void Refresh();
  857.  
  858. static void ClassInitialize()
  859. {
  860.   static XtConvertArgRec screenConvertArg[] = {
  861.   {XtWidgetBaseOffset, (XtPointer) XtOffset(Widget, core.screen),
  862.        sizeof(Screen *)}, 
  863.   };
  864.  
  865.   XtAddConverter(XtRString, XtRBitmap, XmuCvtStringToBitmap,
  866.              screenConvertArg, XtNumber(screenConvertArg));
  867. }
  868.  
  869. static void Initialize(request, new, argv, argc)
  870.     PixmapWidget request, new;
  871.     ArgList argv;
  872.     Cardinal argc;
  873. {
  874.     XGCValues  values;
  875.     XtGCMask   mask;
  876.  
  877.     dpy = XtDisplay(new);
  878.     screen = DefaultScreen(dpy);
  879.     depth = DefaultDepth(dpy,screen);
  880.  
  881.     /* allocate max colors + 1 colorTable entries because 0 is transparent */
  882.     new->pixmap.colorTable = (PWColorInfo **) XtCalloc(1<<depth + 1, 
  883.                                sizeof(PWColorInfo*));
  884.     
  885.     new->pixmap.notify = NULL;
  886.     new->pixmap.cardinal = 0;
  887.     new->pixmap.current = 0;
  888.     new->pixmap.fold = False;
  889.     new->pixmap.changed = False;
  890.     new->pixmap.zooming = False;
  891.     new->pixmap.selection.own = False;
  892.     new->pixmap.selection.limbo = False;
  893.     new->pixmap.clear_pixel = WhitePixel(dpy, screen);
  894.     new->pixmap.hints_cmt = NULL;
  895.     new->pixmap.colors_cmt = NULL;
  896.     new->pixmap.pixels_cmt = NULL;
  897.     new->pixmap.filename = XtNewString(new->pixmap.filename);
  898.  
  899.     new->pixmap.request_stack = (PWRequestStack *)
  900.     XtMalloc(sizeof(PWRequestStack));
  901.     new->pixmap.request_stack[0].request = NULL;
  902.     new->pixmap.request_stack[0].call_data = NULL;
  903.     new->pixmap.request_stack[0].trap = False;
  904.  
  905.     new->core.width = new->pixmap.width * new->pixmap.squareW + 
  906.     2 * new->pixmap.distance;
  907.     new->core.height = new->pixmap.height * new->pixmap.squareH + 
  908.     2 * new->pixmap.distance;
  909.  
  910.     new->pixmap.extensions = NULL;
  911.     new->pixmap.nextensions = 0;
  912.     new->pixmap.buffer_extensions = NULL;
  913.     new->pixmap.buffer_nextensions = 0;
  914.  
  915.     new->pixmap.text_string = NULL;
  916.     new->pixmap.font_struct = NULL;
  917. /*
  918.     PWSetFont(new, "-*-fixed-medium-*-*-*-13-*-*-*-*-70-*-*" );
  919. */
  920.   
  921.     new->pixmap.hot.x = new->pixmap.hot.y = NotSet;
  922.     new->pixmap.buffer_hot.x = new->pixmap.buffer_hot.y = NotSet;
  923.     
  924.     new->pixmap.mark.from_x = new->pixmap.mark.from_y = NotSet;
  925.     new->pixmap.mark.to_x = new->pixmap.mark.to_y = NotSet;
  926.     new->pixmap.buffer_mark.from_x = new->pixmap.buffer_mark.from_y = NotSet;
  927.     new->pixmap.buffer_mark.to_x = new->pixmap.buffer_mark.to_y = NotSet;
  928.  
  929.     values.foreground = new->pixmap.foreground_pixel;
  930.     values.background = new->core.background_pixel;
  931.     values.foreground ^= values.background;
  932.     values.function = GXcopy;
  933.     values.plane_mask = AllPlanes;
  934.     mask = GCForeground | GCBackground | GCFunction | GCPlaneMask;
  935.     new->pixmap.drawing_gc = XCreateGC(dpy, RootWindow(dpy,screen), 
  936.                        mask, &values);
  937.  
  938.     values.foreground = new->pixmap.highlight_pixel;
  939.     values.background = new->core.background_pixel;
  940.     values.foreground ^= values.background;
  941.     values.function = GXxor;
  942.     values.plane_mask = AllPlanes;
  943.     mask = GCForeground | GCBackground | GCFunction | GCPlaneMask;
  944.     new->pixmap.highlighting_gc = XCreateGC(dpy, RootWindow(dpy, screen),
  945.                         mask, &values);
  946.  
  947.     values.foreground = new->pixmap.framing_pixel;
  948.     values.background = new->core.background_pixel;
  949.     values.foreground ^= values.background;
  950.     values.function = GXxor;
  951.     values.plane_mask = AllPlanes;
  952.     mask = GCForeground | GCBackground | GCFunction | GCPlaneMask;
  953.     new->pixmap.framing_gc = XCreateGC(dpy, RootWindow(dpy, screen),
  954.                        mask, &values);
  955.  
  956.     values.foreground = new->pixmap.transparent_pixel;
  957.     values.background = new->pixmap.clear_pixel;
  958.     values.function = GXcopy;
  959.     mask = GCForeground | GCBackground | GCFunction;
  960.     if (new->pixmap.stipple != XtUnspecifiedPixmap)
  961.       {
  962.     values.stipple = new->pixmap.stipple;
  963.     mask |= GCStipple | GCFillStyle;
  964.       }
  965.     values.fill_style = (new->pixmap.stippled ? 
  966.              FillOpaqueStippled : FillSolid);
  967.     new->pixmap.transparent_gc = XCreateGC(dpy, RootWindow(dpy, screen),
  968.                        mask, &values);
  969.     
  970.     new->pixmap.storage = NULL;
  971.  
  972.     new->pixmap.image = CreatePixmapImage(new, 
  973.                       new->pixmap.width,
  974.                       new->pixmap.height);
  975.     new->pixmap.mask_image = CreateMaskImage(new,
  976.                          new->pixmap.width,
  977.                          new->pixmap.height);
  978.     
  979.     new->pixmap.buffer = CreatePixmapImage(new, 
  980.                        new->pixmap.width,
  981.                        new->pixmap.height);
  982.     new->pixmap.mask_buffer = CreateMaskImage(new, 
  983.                           new->pixmap.width,
  984.                           new->pixmap.height);
  985.     
  986.     /* add transparent pixel in ColorTable */
  987.     PWUseColorInTable((Widget)new, TRANSPARENT(dpy, screen), NULL,
  988.               NULL, NULL, NULL, NULL, NoColorName);
  989.     if (new->pixmap.AddColorNotify != (AddColorNotifyProc) 0)
  990.       new->pixmap.AddColorNotify((Widget)new, TRANSPARENT(dpy, screen), 
  991.                  NoColorName);
  992.     
  993.     /* add clear pixel in ColorTable */
  994.     PWUseColorInTable((Widget)new, new->pixmap.clear_pixel, NULL,
  995.               NULL, NULL, NULL, NULL, "white");
  996.     if (new->pixmap.AddColorNotify != (AddColorNotifyProc) 0)
  997.       new->pixmap.AddColorNotify((Widget)new, new->pixmap.clear_pixel, 
  998.                  "white");
  999.     
  1000.     /* Read file */
  1001.     {
  1002.     int status;
  1003.     XImage *image, *mask_image, *buffer, *mask_buffer;
  1004.     char  *buffer_data;
  1005.     XpmAttributes attribs;
  1006.  
  1007.     InitializeXpmAttributes(&attribs);
  1008.     attribs.visual = DefaultVisual(dpy, screen);
  1009.     attribs.colormap = DefaultColormap(dpy, screen);
  1010.     attribs.depth = depth;
  1011.     attribs.colorsymbols = (XpmColorSymbol *)NULL;
  1012.     attribs.numsymbols = 0;
  1013.     attribs.nextensions = 0;
  1014.     attribs.valuemask = XpmVisual | XpmColormap | XpmDepth | 
  1015.       XpmReturnPixels | XpmReturnInfos | XpmExtensions;
  1016.     
  1017.     status = XpmReadFileToImage(dpy, new->pixmap.filename, &image,
  1018.                    &mask_image, &attribs);
  1019.     
  1020.     if (status == XpmSuccess) 
  1021.       {
  1022.         
  1023.         { /* Notify colors to be loaded with this pixmap */
  1024.           int i, shift = 0, offset;
  1025.           
  1026.           switch (depth)
  1027.         {
  1028.         case 1:
  1029.           offset = 2;
  1030.           break;
  1031.         case 4:
  1032.           offset = 3;
  1033.           break;
  1034.         case 6:
  1035.           offset = 4;
  1036.           break;
  1037.         case 8:
  1038.         default:
  1039.           offset = 5;
  1040.           break;
  1041.         }
  1042.           
  1043.           for (i = 0; i < attribs.ncolors; i++)
  1044.         {
  1045.           if (_PWDEBUG) {
  1046.             printf("Pixel %d\n", *(attribs.pixels+i-shift));
  1047.             printf("Color name %s\n", 
  1048.                *(*(attribs.colorTable+i)+offset));
  1049.             printf("colorTable[%d][0] %s\n", i,
  1050.                **(attribs.colorTable+i));
  1051.             printf("colorTable[%d][1] %s\n", i, 
  1052.                *(*(attribs.colorTable+i)+1));
  1053.             printf("colorTable[%d][2] %s\n", i, 
  1054.                *(*(attribs.colorTable+i)+2));
  1055.             printf("colorTable[%d][3] %s\n", i, 
  1056.                *(*(attribs.colorTable+i)+3));
  1057.             printf("colorTable[%d][4] %s\n", i, 
  1058.                *(*(attribs.colorTable+i)+4));
  1059.             printf("colorTable[%d][5] %s\n", i, 
  1060.                *(*(attribs.colorTable+i)+5));
  1061.           }
  1062.  
  1063.           if ((attribs.mask_pixel != UNDEF_PIXEL) && 
  1064.               (i == attribs.mask_pixel)) 
  1065.             {
  1066.               PWUpdateColorInTable((Widget)new, 
  1067.                        TRANSPARENT(dpy, screen), 
  1068.                        *(*(attribs.colorTable+i)), 
  1069.                        *(*(attribs.colorTable+i)+1),
  1070.                        *(*(attribs.colorTable+i)+2),
  1071.                        *(*(attribs.colorTable+i)+3),
  1072.                        *(*(attribs.colorTable+i)+4),
  1073.                        *(*(attribs.colorTable+i)+5));
  1074.               shift = 1;
  1075.             }
  1076.           else 
  1077.             {
  1078.               PWUseColorInTable((Widget)new, 
  1079.                     *(attribs.pixels+i-shift), 
  1080.                     *(*(attribs.colorTable+i)), 
  1081.                     *(*(attribs.colorTable+i)+1),
  1082.                     *(*(attribs.colorTable+i)+2),
  1083.                     *(*(attribs.colorTable+i)+3),
  1084.                     *(*(attribs.colorTable+i)+4),
  1085.                     *(*(attribs.colorTable+i)+5));
  1086.               if (new->pixmap.AddColorNotify != (AddColorNotifyProc) 0)
  1087.             new->pixmap.AddColorNotify((Widget)new, 
  1088.                            *(attribs.pixels+i-shift), 
  1089.                            *(*(attribs.colorTable+i)
  1090.                              +offset));
  1091.             }
  1092.         }
  1093.           
  1094.           if (new->pixmap.hints_cmt) XtFree(new->pixmap.hints_cmt);
  1095.           if (attribs.hints_cmt) 
  1096.         new->pixmap.hints_cmt = XtNewString(attribs.hints_cmt);
  1097.           if (new->pixmap.colors_cmt) XtFree(new->pixmap.colors_cmt);
  1098.           if (attribs.colors_cmt) 
  1099.         new->pixmap.colors_cmt = XtNewString(attribs.colors_cmt);
  1100.           if (new->pixmap.pixels_cmt) XtFree(new->pixmap.pixels_cmt);
  1101.           if (attribs.pixels_cmt) 
  1102.         new->pixmap.pixels_cmt = XtNewString(attribs.pixels_cmt);
  1103.           
  1104.         }
  1105.       
  1106.         if (!mask_image) /* Xpm returns NULL when transp. is not used */
  1107.           mask_image = CreateMaskImage(new, image->width, image->height);
  1108.         else SetTransparentPixels(new, image, mask_image);
  1109.  
  1110.         buffer = CreatePixmapImage(new, new->pixmap.image->width, 
  1111.                        new->pixmap.image->height);
  1112.         mask_buffer = CreateMaskImage(new, new->pixmap.image->width, 
  1113.                       new->pixmap.image->height); 
  1114.     
  1115.         TransferImageData(new->pixmap.image, buffer);
  1116.         TransferImageData(new->pixmap.mask_image, mask_buffer);
  1117.     
  1118.         DestroyPixmapImage(&new->pixmap.image);
  1119.         DestroyPixmapImage(&new->pixmap.buffer);
  1120.         DestroyMaskImage(&new->pixmap.mask_image);
  1121.         DestroyMaskImage(&new->pixmap.mask_buffer);
  1122.  
  1123.         new->pixmap.image = image;
  1124.         new->pixmap.mask_image = mask_image;
  1125.         new->pixmap.buffer = buffer;
  1126.         new->pixmap.mask_buffer = mask_buffer;
  1127.         new->pixmap.width = attribs.width;
  1128.         new->pixmap.height = attribs.height;
  1129.  
  1130.         if (attribs.valuemask & XpmHotspot)
  1131.           {
  1132.         new->pixmap.hot.x = attribs.x_hotspot;
  1133.         new->pixmap.hot.y = attribs.y_hotspot;    
  1134.           }
  1135.  
  1136.             CopyExtensions( &new->pixmap.extensions, &new->pixmap.nextensions,
  1137.                             attribs.extensions, attribs.nextensions );
  1138.             if (new->pixmap.extensionNotify)
  1139.                 new->pixmap.extensionNotify ((Widget) new);
  1140.         
  1141.         new->pixmap.changed = False;
  1142.         new->pixmap.zooming = False;
  1143.         XpmFreeAttributes(&attribs);
  1144.           }
  1145.     }
  1146.  
  1147.     InternalResize(new);
  1148.     Resize(new);
  1149. }
  1150.  
  1151. #if NeedFunctionPrototypes
  1152. Boolean PWQueryMarked(Widget w)
  1153. #else
  1154. Boolean PWQueryMarked(w)
  1155.     Widget w;
  1156. #endif
  1157. {
  1158.     PixmapWidget PW = (PixmapWidget) w;
  1159.  
  1160.     return QuerySet(PW->pixmap.mark.from_x, PW->pixmap.mark.from_y);
  1161. }
  1162.  
  1163. #if NeedFunctionPrototypes
  1164. Boolean PWQueryStippled(Widget w)
  1165. #else
  1166. Boolean PWQueryStippled(w)
  1167.      Widget w;
  1168. #endif
  1169. {
  1170.   PixmapWidget PW = (PixmapWidget) w;
  1171.   
  1172.   return(PW->pixmap.stippled);
  1173. }
  1174.  
  1175. void FixMark(PW)
  1176.     PixmapWidget PW;
  1177. {
  1178.     if (QuerySet(PW->pixmap.mark.from_x, PW->pixmap.mark.from_y)) {
  1179.     PW->pixmap.mark.from_x = min(PW->pixmap.mark.from_x, 
  1180.                      PW->pixmap.image->width);
  1181.     PW->pixmap.mark.from_y = min(PW->pixmap.mark.from_y, 
  1182.                      PW->pixmap.image->height);
  1183.     PW->pixmap.mark.to_x = min(PW->pixmap.mark.to_x, 
  1184.                    PW->pixmap.image->width);
  1185.     PW->pixmap.mark.to_y = min(PW->pixmap.mark.to_y, 
  1186.                    PW->pixmap.image->height);
  1187.     
  1188.     if((PW->pixmap.mark.from_x == PW->pixmap.mark.from_y) &&
  1189.        (PW->pixmap.mark.to_x   == PW->pixmap.mark.to_y))
  1190.         PW->pixmap.mark.from_x = 
  1191.         PW->pixmap.mark.from_y =
  1192.             PW->pixmap.mark.to_x = 
  1193.             PW->pixmap.mark.to_y = NotSet;
  1194.     }
  1195. }
  1196.  
  1197. #if NeedFunctionPrototypes
  1198. int PWStoreFile(Widget w, String filename)
  1199. #else
  1200. int PWStoreFile(w, filename)
  1201.     Widget w;
  1202.     String filename;
  1203. #endif
  1204. {
  1205.     PixmapWidget PW = (PixmapWidget) w;
  1206.     int status;
  1207.     XImage *image, *mask_image;
  1208.     XpmAttributes attribs;
  1209.     unsigned int width, height;
  1210.     
  1211.     InitializeXpmAttributes(&attribs);
  1212.     attribs.visual = DefaultVisual(dpy, screen);
  1213.     attribs.colormap = DefaultColormap(dpy, screen);
  1214.     attribs.depth = depth;
  1215.     attribs.colorsymbols = (XpmColorSymbol *)NULL;
  1216.     attribs.numsymbols = 0;
  1217.     attribs.nextensions = 0;
  1218.     attribs.valuemask = XpmVisual | XpmColormap | XpmDepth | 
  1219.       XpmReturnPixels | XpmReturnInfos ;
  1220.     
  1221.     status = XpmReadFileToImage(dpy, filename, &image, &mask_image, &attribs);
  1222.  
  1223.     if (status == XpmSuccess) {
  1224.  
  1225.       { /* Notify colors to be loaded with this pixmap */
  1226.     int i, offset, shift = 0;
  1227.     
  1228.     switch (depth)
  1229.       {
  1230.       case 1:
  1231.         offset = 2; /* BW display */
  1232.         break;
  1233.       case 4:
  1234.         offset = 3; /* G4 display */
  1235.         break;
  1236.       case 6:
  1237.         offset = 4; /* G6 display */
  1238.         break;
  1239.       case 8:
  1240.       default:
  1241.         offset = 5; /* Color display */
  1242.         break;
  1243.       }
  1244.     
  1245.     for (i = 0; i < attribs.ncolors; i++)
  1246.       {
  1247.         if (_PWDEBUG) {
  1248.           printf("Pixel %d\n", *(attribs.pixels+i-shift));
  1249.           printf("Color name %s\n", *(*(attribs.colorTable+i)+offset));
  1250.           printf("colorTable[%d][0] %s\n", i, **(attribs.colorTable+i));
  1251.           printf("colorTable[%d][1] %s\n", i,*(*(attribs.colorTable+i)+1));
  1252.           printf("colorTable[%d][2] %s\n", i,*(*(attribs.colorTable+i)+2));
  1253.           printf("colorTable[%d][3] %s\n", i,*(*(attribs.colorTable+i)+3));
  1254.           printf("colorTable[%d][4] %s\n", i,*(*(attribs.colorTable+i)+4));
  1255.           printf("colorTable[%d][5] %s\n", i,*(*(attribs.colorTable+i)+5));
  1256.         }
  1257.         
  1258.         if ((attribs.mask_pixel != UNDEF_PIXEL) && 
  1259.          (i == attribs.mask_pixel)) 
  1260.           {
  1261.         PWUpdateColorInTable((Widget)PW, TRANSPARENT(dpy, screen), 
  1262.                      *(*(attribs.colorTable+i)), 
  1263.                      *(*(attribs.colorTable+i)+1),
  1264.                      *(*(attribs.colorTable+i)+2),
  1265.                      *(*(attribs.colorTable+i)+3),
  1266.                      *(*(attribs.colorTable+i)+4),
  1267.                      *(*(attribs.colorTable+i)+5));
  1268.         shift = 1;
  1269.           }
  1270.         else 
  1271.           {
  1272.         PWUseColorInTable((Widget)PW, *(attribs.pixels+i-shift), 
  1273.                   *(*(attribs.colorTable+i)), 
  1274.                   *(*(attribs.colorTable+i)+1),
  1275.                   *(*(attribs.colorTable+i)+2),
  1276.                   *(*(attribs.colorTable+i)+3),
  1277.                   *(*(attribs.colorTable+i)+4),
  1278.                   *(*(attribs.colorTable+i)+5));
  1279.         if (PW->pixmap.AddColorNotify != (AddColorNotifyProc) 0)
  1280.           PW->pixmap.AddColorNotify((Widget)PW, 
  1281.                         *(attribs.pixels+i-shift), 
  1282.                         *(*(attribs.colorTable+i)+offset));
  1283.           }
  1284.       }
  1285.       }
  1286.     
  1287.         if (!mask_image) /* Xpm returns NULL when transp. is not used */
  1288.       mask_image = CreateMaskImage(PW, image->width, image->height);
  1289.         else SetTransparentPixels(PW, image, mask_image);
  1290.       
  1291.         DestroyPixmapImage(&PW->pixmap.storage);
  1292.         DestroyMaskImage(&PW->pixmap.mask_storage);
  1293.  
  1294.         PW->pixmap.storage = image;
  1295.         PW->pixmap.mask_storage = mask_image;
  1296.     
  1297.         if (attribs.valuemask & XpmHotspot)
  1298.       {
  1299.         PW->pixmap.storage_hot.x = attribs.x_hotspot;
  1300.         PW->pixmap.storage_hot.y = attribs.y_hotspot;    
  1301.       }
  1302.         else
  1303.       {
  1304.         PW->pixmap.storage_hot.x = PW->pixmap.storage_hot.y = NotSet;
  1305.       }
  1306.  
  1307.     XpmFreeAttributes(&attribs);
  1308.     }
  1309.     else
  1310.     XtAppWarning(XtWidgetToApplicationContext(w),
  1311.              " read file failed.  PixmapWidget");
  1312.     
  1313.     return status;
  1314. }
  1315.  
  1316. #if NeedFunctionPrototypes
  1317. String PWUnparseStatus(Widget w)
  1318. #else
  1319. String PWUnparseStatus(w)
  1320.     Widget w;
  1321. #endif
  1322. {
  1323.     PixmapWidget PW = (PixmapWidget) w;
  1324.     
  1325.     sprintf(PW->pixmap.status, 
  1326.         "Filename: %s Size:%dx%d",
  1327.         PW->pixmap.filename, PW->pixmap.width, PW->pixmap.height);
  1328.  
  1329.     return PW->pixmap.status;
  1330. }
  1331.  
  1332.     
  1333. #if NeedFunctionPrototypes
  1334. void PWChangeFilename(Widget w, String str)
  1335. #else
  1336. void PWChangeFilename(w, str)
  1337.     Widget w;
  1338.     String str;
  1339. #endif
  1340. {
  1341.     PixmapWidget PW = (PixmapWidget) w;
  1342.     
  1343.     if (str)
  1344.     if (strcmp(str, "")) {
  1345.         XtFree(PW->pixmap.filename);
  1346.         PW->pixmap.filename = XtNewString( str);
  1347.     }
  1348. }
  1349.  
  1350.  
  1351. /* Warning this function sets or gets the pixmap comments 
  1352.  * if passing null, a comment is returned, otherwise, it is stored 
  1353.  * memory is allocated for returned comments, should be free by application */
  1354. #if NeedFunctionPrototypes
  1355. void PWComments(Widget w, char **hints_cmt, char **colors_cmt, 
  1356.         char **pixels_cmt)
  1357. #else
  1358. void PWComments(w, hints_cmt, colors_cmt, pixels_cmt)
  1359.      Widget w;
  1360.      char **hints_cmt, **colors_cmt, **pixels_cmt;
  1361. #endif
  1362. {
  1363.   PixmapWidget PW = (PixmapWidget)w;
  1364.   
  1365.   if ((*hints_cmt) && (PW->pixmap.hints_cmt))
  1366.     {
  1367.       XtFree(PW->pixmap.hints_cmt);
  1368.       PW->pixmap.hints_cmt = XtNewString(*hints_cmt);
  1369.     }
  1370.   else if (*hints_cmt) PW->pixmap.hints_cmt = XtNewString(*hints_cmt);
  1371.   else *hints_cmt = XtNewString(PW->pixmap.hints_cmt);
  1372.  
  1373.   if ((*colors_cmt) && (PW->pixmap.colors_cmt))
  1374.     {
  1375.       XtFree(PW->pixmap.colors_cmt);
  1376.       PW->pixmap.colors_cmt = XtNewString(*colors_cmt);
  1377.     }
  1378.   else if (*colors_cmt) PW->pixmap.colors_cmt = XtNewString(*colors_cmt);
  1379.   else *colors_cmt = XtNewString(PW->pixmap.colors_cmt);
  1380.  
  1381.   if ((*pixels_cmt) && (PW->pixmap.pixels_cmt))
  1382.     {
  1383.       XtFree(PW->pixmap.pixels_cmt);
  1384.       PW->pixmap.pixels_cmt = XtNewString(*pixels_cmt);
  1385.     }
  1386.   else if (*pixels_cmt) PW->pixmap.pixels_cmt = XtNewString(*pixels_cmt);
  1387.   else *pixels_cmt = XtNewString(PW->pixmap.pixels_cmt);
  1388. }
  1389.  
  1390.   
  1391. #if NeedFunctionPrototypes
  1392. void PWAddColorNotifyProc(Widget w, AddColorNotifyProc proc)
  1393. #else
  1394. void PWAddColorNotifyProc(w, proc)
  1395.      Widget w;
  1396.      AddColorNotifyProc proc;
  1397. #endif
  1398. {
  1399.   PixmapWidget PW = (PixmapWidget) w;
  1400.   
  1401.   PW->pixmap.AddColorNotify = proc;
  1402. }
  1403.  
  1404.  
  1405. #if NeedFunctionPrototypes
  1406. PWColorInfo **PWGetColorTable(Widget w)
  1407. #else
  1408. PWColorInfo **PWGetColorTable(w)
  1409.      Widget w;
  1410. #endif
  1411. {
  1412.   PixmapWidget PW = (PixmapWidget) w;
  1413.   
  1414.   return(PW->pixmap.colorTable);
  1415. }
  1416.  
  1417. #if NeedFunctionPrototypes
  1418. void PWUseColorInTable(Widget w, Pixel pixel, char *symbol, char *sname, 
  1419.                char *mname, char *g4name, char *gname, char *cname)
  1420. #else
  1421. void PWUseColorInTable(w, pixel, symbol, sname, mname, g4name, gname, cname)
  1422.      Widget w;
  1423.      Pixel pixel;
  1424.      char *symbol, *sname, *mname, *g4name, *gname, *cname;
  1425. #endif
  1426.      /* name are not used as is, instead memory is malloc'ed to fit in */
  1427. {
  1428.   PixmapWidget PW = (PixmapWidget) w;
  1429.   /* index in colorTable is 0 for transparent and pixel+1 for others */
  1430.   int index = (pixel == TRANSPARENT(dpy, screen) ? 0 : pixel + 1);
  1431.   
  1432.   if (!PW->pixmap.colorTable[index])  /* not yet used color 
  1433.                      probably not in colorTable */
  1434.     {
  1435.       PW->pixmap.colorTable[index]=(PWColorInfo*)XtCalloc(1,
  1436.                               sizeof(PWColorInfo));
  1437.       PW->pixmap.colorTable[index]->symbol = 0;
  1438.       PW->pixmap.colorTable[index]->s_name = 0;
  1439.       PW->pixmap.colorTable[index]->m_name = 0;
  1440.       PW->pixmap.colorTable[index]->g4_name = 0;
  1441.       PW->pixmap.colorTable[index]->g_name = 0;
  1442.       PW->pixmap.colorTable[index]->c_name = 0;
  1443.       PW->pixmap.colorTable[index]->pixel = pixel;
  1444.     }
  1445.   
  1446.   PWUpdateColorInTable(w, pixel, symbol, sname, mname, g4name, 
  1447.                gname, cname);
  1448.  
  1449. }
  1450.  
  1451.  
  1452. #if NeedFunctionPrototypes
  1453. void PWUpdateColorInTable(Widget w, Pixel pixel, char *symbol, char *sname, 
  1454.                char *mname, char *g4name, char *gname, char *cname)
  1455. #else
  1456. void PWUpdateColorInTable(w, pixel, symbol, sname, mname, g4name, gname, cname)
  1457.      Widget w;
  1458.      Pixel pixel;
  1459.      char *symbol, *sname, *mname, *g4name, *gname, *cname;
  1460. #endif
  1461.      /* name are not used as is, instead memory is malloc'ed to fit in */
  1462. {
  1463.   PixmapWidget PW = (PixmapWidget) w;
  1464.   /* index in colorTable is 0 for transparent and pixel+1 for others */
  1465.   int index = (pixel == TRANSPARENT(dpy, screen) ? 0 : pixel + 1);
  1466.   
  1467.   if (!PW->pixmap.colorTable[index]) return; /* inexistent color in Table */
  1468.   /* Update the color info in ColorTable */
  1469.   if ((symbol) && ((!PW->pixmap.colorTable[index]->symbol) || 
  1470.            (strcmp(symbol, PW->pixmap.colorTable[index]->symbol))))
  1471.     {
  1472.       if (PW->pixmap.colorTable[index]->symbol) 
  1473.     XtFree(PW->pixmap.colorTable[index]->symbol);
  1474.       PW->pixmap.colorTable[index]->symbol = XtNewString(symbol);
  1475.     }
  1476.   if ((sname) && ((!PW->pixmap.colorTable[index]->s_name) ||
  1477.           (strcmp(sname, PW->pixmap.colorTable[index]->s_name))))
  1478.     {
  1479.       if (PW->pixmap.colorTable[index]->s_name) 
  1480.     XtFree(PW->pixmap.colorTable[index]->s_name);
  1481.       PW->pixmap.colorTable[index]->s_name = XtNewString(sname);
  1482.     }
  1483.   if ((mname) && ((!PW->pixmap.colorTable[index]->m_name) ||
  1484.           (strcmp(mname, PW->pixmap.colorTable[index]->m_name))))
  1485.     {
  1486.       if (PW->pixmap.colorTable[index]->m_name) 
  1487.     XtFree(PW->pixmap.colorTable[index]->m_name);
  1488.       PW->pixmap.colorTable[index]->m_name = XtNewString(mname);
  1489.     }
  1490.   if ((g4name) && ((!PW->pixmap.colorTable[index]->g4_name) ||
  1491.            (strcmp(g4name, PW->pixmap.colorTable[index]->g4_name))))
  1492.     {
  1493.       if (PW->pixmap.colorTable[index]->g4_name) 
  1494.     XtFree(PW->pixmap.colorTable[index]->g4_name);
  1495.       PW->pixmap.colorTable[index]->g4_name = XtNewString(g4name);
  1496.     }
  1497.   if ((gname) && ((!PW->pixmap.colorTable[index]->g_name) ||
  1498.           (strcmp(gname, PW->pixmap.colorTable[index]->g_name))))
  1499.     {
  1500.       if (PW->pixmap.colorTable[index]->g_name) 
  1501.     XtFree(PW->pixmap.colorTable[index]->g_name);
  1502.       PW->pixmap.colorTable[index]->g_name = XtNewString(gname);
  1503.     }
  1504.   if ((cname) && ((!PW->pixmap.colorTable[index]->c_name) ||
  1505.            ((strcmp(cname, PW->pixmap.colorTable[index]->c_name)) &&
  1506.             ((cname[0] != '#') || 
  1507.              (PW->pixmap.colorTable[index]->c_name[0] == '#')))))
  1508.     {
  1509.       if (PW->pixmap.colorTable[index]->c_name) 
  1510.     XtFree(PW->pixmap.colorTable[index]->c_name);
  1511.       PW->pixmap.colorTable[index]->c_name = XtNewString(cname);
  1512.     }
  1513.   else if ((!cname) && (!PW->pixmap.colorTable[index]->c_name))
  1514.     {
  1515.       XColor color;
  1516.  
  1517.       color.pixel = pixel;
  1518.       XQueryColor(dpy, DefaultColormap(dpy, screen), &color);
  1519.       
  1520.       PW->pixmap.colorTable[index]->c_name = (char *)XtMalloc(15*sizeof(char));
  1521.       sprintf(PW->pixmap.colorTable[index]->c_name, "#%04X%04X%04X", 
  1522.           color.red, color.green, color.blue);
  1523.     }
  1524.   
  1525. }
  1526.     
  1527. #if NeedFunctionPrototypes
  1528. int PWReadFile(Widget w, String filename)
  1529. #else
  1530. int PWReadFile(w, filename)
  1531.     Widget w;
  1532.     String filename;
  1533. #endif
  1534. {
  1535.     PixmapWidget PW = (PixmapWidget) w;
  1536.     int status;
  1537.     XImage *image, *mask_image, *buffer, *mask_buffer;
  1538.     XpmAttributes attribs;
  1539.     
  1540.     InitializeXpmAttributes(&attribs);
  1541.     attribs.visual = DefaultVisual(dpy, screen);
  1542.     attribs.colormap = DefaultColormap(dpy, screen);
  1543.     attribs.depth = depth;
  1544.     attribs.colorsymbols = (XpmColorSymbol *)NULL;
  1545.     attribs.numsymbols = 0;
  1546.     attribs.nextensions = 0;
  1547.     attribs.valuemask = XpmVisual | XpmColormap | XpmDepth | 
  1548.       XpmReturnPixels | XpmReturnInfos | XpmExtensions;
  1549.     
  1550.     status = XpmReadFileToImage(dpy, filename, &image, &mask_image, &attribs);
  1551.       
  1552.     if (status == XpmSuccess) {
  1553.     
  1554.       { /* Notify colors to be loaded with this pixmap */
  1555.     int i, offset, shift = 0;
  1556.     
  1557.     switch (depth)
  1558.       {
  1559.       case 1:
  1560.         offset = 2; /* BW display */
  1561.         break;
  1562.       case 4:
  1563.         offset = 3; /* G4 display */
  1564.         break;
  1565.       case 6:
  1566.         offset = 4; /* G6 display */
  1567.         break;
  1568.       case 8:
  1569.       default:
  1570.         offset = 5; /* Color display */
  1571.         break;
  1572.       }
  1573.     
  1574.     for (i = 0; i < attribs.ncolors; i++)
  1575.       {
  1576.         if (_PWDEBUG) {
  1577.           printf("Pixel %d\n", *(attribs.pixels+i-shift));
  1578.           printf("Color name %s\n", *(*(attribs.colorTable+i)+offset));
  1579.           printf("colorTable[%d][0] %s\n", i,**(attribs.colorTable+i));
  1580.           printf("colorTable[%d][1] %s\n", i,*(*(attribs.colorTable+i)+1));
  1581.           printf("colorTable[%d][2] %s\n", i,*(*(attribs.colorTable+i)+2));
  1582.           printf("colorTable[%d][3] %s\n", i,*(*(attribs.colorTable+i)+3));
  1583.           printf("colorTable[%d][4] %s\n", i,*(*(attribs.colorTable+i)+4));
  1584.           printf("colorTable[%d][5] %s\n", i,*(*(attribs.colorTable+i)+5));
  1585.         }
  1586.  
  1587.         if ((attribs.mask_pixel != UNDEF_PIXEL) && 
  1588.         (i == attribs.mask_pixel)) 
  1589.           {
  1590.         PWUpdateColorInTable((Widget)PW, TRANSPARENT(dpy, screen), 
  1591.                      *(*(attribs.colorTable+i)), 
  1592.                      *(*(attribs.colorTable+i)+1),
  1593.                      *(*(attribs.colorTable+i)+2),
  1594.                      *(*(attribs.colorTable+i)+3),
  1595.                      *(*(attribs.colorTable+i)+4),
  1596.                      *(*(attribs.colorTable+i)+5));
  1597.         shift = 1;
  1598.           }
  1599.         else 
  1600.           {
  1601.         PWUseColorInTable((Widget) PW, *(attribs.pixels+i-shift), 
  1602.                   *(*(attribs.colorTable+i)), 
  1603.                   *(*(attribs.colorTable+i)+1),
  1604.                   *(*(attribs.colorTable+i)+2),
  1605.                   *(*(attribs.colorTable+i)+3),
  1606.                   *(*(attribs.colorTable+i)+4),
  1607.                   *(*(attribs.colorTable+i)+5));
  1608.         if (PW->pixmap.AddColorNotify != (AddColorNotifyProc) 0)
  1609.           PW->pixmap.AddColorNotify((Widget) PW, 
  1610.                         *(attribs.pixels+i-shift), 
  1611.                         *(*(attribs.colorTable+i)+offset));
  1612.           }
  1613.       }
  1614.  
  1615.     if (PW->pixmap.hints_cmt) XtFree(PW->pixmap.hints_cmt);
  1616.     if (attribs.hints_cmt) 
  1617.       PW->pixmap.hints_cmt = XtNewString(attribs.hints_cmt);
  1618.     if (PW->pixmap.colors_cmt) XtFree(PW->pixmap.colors_cmt);
  1619.     if (attribs.colors_cmt) 
  1620.       PW->pixmap.colors_cmt = XtNewString(attribs.colors_cmt);
  1621.     if (PW->pixmap.pixels_cmt) XtFree(PW->pixmap.pixels_cmt);
  1622.     if (attribs.pixels_cmt) 
  1623.       PW->pixmap.pixels_cmt = XtNewString(attribs.pixels_cmt);
  1624.  
  1625.       }
  1626.     
  1627.         if (!mask_image) /* Xpm returns NULL when transp. is not used */
  1628.       mask_image = CreateMaskImage(PW, image->width, image->height);
  1629.         else SetTransparentPixels(PW, image, mask_image);
  1630.       
  1631.     buffer = CreatePixmapImage(PW, PW->pixmap.image->width, 
  1632.                    PW->pixmap.image->height);
  1633.         mask_buffer = CreateMaskImage(PW, PW->pixmap.image->width, 
  1634.                       PW->pixmap.image->height);
  1635.     
  1636.     TransferImageData(PW->pixmap.image, buffer);
  1637.         TransferImageData(PW->pixmap.mask_image, mask_buffer);
  1638.     
  1639.     DestroyPixmapImage(&PW->pixmap.image);
  1640.     DestroyPixmapImage(&PW->pixmap.buffer);
  1641.     DestroyMaskImage(&PW->pixmap.mask_image);
  1642.     DestroyMaskImage(&PW->pixmap.mask_buffer);
  1643.     
  1644.     PW->pixmap.image = image;
  1645.         PW->pixmap.mask_image = mask_image;
  1646.     PW->pixmap.buffer = buffer;
  1647.         PW->pixmap.mask_buffer = mask_buffer;
  1648.     PW->pixmap.width = attribs.width;
  1649.     PW->pixmap.height = attribs.height;
  1650.       
  1651.         if (attribs.valuemask & XpmHotspot)
  1652.       {
  1653.         PW->pixmap.hot.x = attribs.x_hotspot;
  1654.         PW->pixmap.hot.y = attribs.y_hotspot;    
  1655.       }
  1656.         else
  1657.       {
  1658.         PW->pixmap.hot.x = PW->pixmap.hot.y = NotSet;
  1659.       }
  1660.  
  1661.         CopyExtensions( &PW->pixmap.extensions, &PW->pixmap.nextensions,
  1662.                         attribs.extensions, attribs.nextensions );
  1663.         if (PW->pixmap.extensionNotify)
  1664.             PW->pixmap.extensionNotify ((Widget) PW);
  1665.  
  1666.     PW->pixmap.changed = False;
  1667.     PW->pixmap.zooming = False;
  1668.     
  1669.     XtFree(PW->pixmap.filename);
  1670.     PW->pixmap.filename = XtNewString(filename);
  1671.  
  1672.     PWUnmark(w);
  1673.     
  1674.     InternalResize(PW);
  1675.  
  1676.     if (PW->core.visible) {
  1677.         XClearArea(dpy, XtWindow(PW),
  1678.                0, 0, 
  1679.                PW->core.width, PW->core.height,
  1680.                True);
  1681.     }
  1682.     
  1683.     XpmFreeAttributes(&attribs);
  1684.     }
  1685.     else
  1686.     XtAppWarning(XtWidgetToApplicationContext(w),
  1687.              " read file failed.  PixmapWidget");
  1688.     
  1689.     return status;
  1690. }
  1691.  
  1692. #if NeedFunctionPrototypes
  1693. void PWSetImage(Widget w, XImage *image, XImage *mask_image)
  1694. #else
  1695. void PWSetImage(w, image, mask_image)
  1696.     Widget w;
  1697.     XImage *image, *mask_image;
  1698. #endif
  1699. {
  1700.     PixmapWidget PW = (PixmapWidget) w;
  1701.     XImage *buffer, *mask_buffer;
  1702.     
  1703.     buffer = CreatePixmapImage(PW, 
  1704.                    (Dimension) image->width, 
  1705.                    (Dimension) image->height);
  1706.     mask_buffer = CreateMaskImage(PW, 
  1707.                   (Dimension) image->width, 
  1708.                   (Dimension) image->height);
  1709.     
  1710.     TransferImageData(PW->pixmap.image, buffer);
  1711.     TransferImageData(PW->pixmap.mask_image, mask_buffer);
  1712.     
  1713.     DestroyPixmapImage(&PW->pixmap.image);
  1714.     DestroyPixmapImage(&PW->pixmap.buffer);
  1715.     DestroyMaskImage(&PW->pixmap.mask_image);
  1716.     DestroyMaskImage(&PW->pixmap.mask_buffer);
  1717.     
  1718.     PW->pixmap.image = image;
  1719.     PW->pixmap.mask_image = mask_image;
  1720.     PW->pixmap.buffer = buffer;
  1721.     PW->pixmap.mask_buffer = mask_buffer;
  1722.     PW->pixmap.width = image->width;
  1723.     PW->pixmap.height = image->height;
  1724.     
  1725.     InternalResize(PW);
  1726.     
  1727.     if (PW->core.visible) {
  1728.     XClearArea(dpy, XtWindow(PW),
  1729.            0, 0, 
  1730.            PW->core.width, PW->core.height,
  1731.            True);    
  1732.     }
  1733. }
  1734.  
  1735.  
  1736. XpmAttributes *fillXpmAttributesStruct(PW, image, mask_image)
  1737.      PixmapWidget PW;
  1738.      XImage *image;
  1739.      XImage *mask_image;
  1740. {
  1741.   XpmAttributes *attribs = (XpmAttributes *)XtCalloc(1, XpmAttributesSize());
  1742.   int i,j = 0, k = 0;
  1743.   char *InUse;
  1744.  
  1745.   attribs->valuemask = XpmRgbFilename | XpmInfos ;
  1746.   attribs->rgb_fname = XtNewString(rgb_fname);
  1747.   attribs->npixels = 0;
  1748.   attribs->cpp = 0;
  1749.   attribs->numsymbols = 0;
  1750.   attribs->colorsymbols = NULL;
  1751.   attribs->ncolors = 0;
  1752.   attribs->mask_pixel = 0;
  1753.   attribs->colormap = DefaultColormap(dpy, screen);
  1754.   attribs->valuemask |= XpmColormap;
  1755.   attribs->depth = depth;
  1756.   attribs->valuemask |= XpmDepth;
  1757.   attribs->width = image->width;
  1758.   attribs->height = image->height;
  1759.   attribs->valuemask |= XpmSize;
  1760.   
  1761.   
  1762.   /* compute number of colors in pixmap */
  1763.   InUse = ReadColorsInUse(image, mask_image, attribs);
  1764.   /* now allocate memory space for colors */
  1765.   attribs->colorTable = (char ***)XtCalloc(attribs->ncolors, sizeof(char **));
  1766.   if (attribs->mask_pixel)
  1767.     { /* store transparent color as first in colorTable */
  1768.       attribs->npixels = attribs->ncolors - 1;
  1769.       i = 0; /* the first entry in colorTable is reserved for transparent */
  1770.       attribs->colorTable[0] = (char **)XtCalloc(6, sizeof(char *));
  1771.       attribs->colorTable[0][0] = 
  1772.     XtNewString(PW->pixmap.colorTable[i]->symbol);
  1773.       attribs->colorTable[0][1] = 
  1774.     XtNewString(PW->pixmap.colorTable[i]->s_name);
  1775.       attribs->colorTable[0][2] = 
  1776.     XtNewString(PW->pixmap.colorTable[i]->m_name);
  1777.       attribs->colorTable[0][3] = 
  1778.     XtNewString(PW->pixmap.colorTable[i]->g4_name);
  1779.       attribs->colorTable[0][4] = 
  1780.     XtNewString(PW->pixmap.colorTable[i]->g_name);
  1781.       attribs->colorTable[0][5] = 
  1782.     XtNewString(PW->pixmap.colorTable[i]->c_name);
  1783.       j = 1;
  1784.     }
  1785.   else attribs->npixels = attribs->ncolors;
  1786.  
  1787.   /* allocate space for pixels */
  1788.   attribs->pixels = (Pixel *)XtCalloc(attribs->npixels, sizeof(Pixel));
  1789.   
  1790.   /* fill in pixels and colorTable */
  1791.   for (i = j; i < attribs->ncolors; i++)
  1792.     {
  1793.       for (k; k < 1<<depth; k++) /* find next used color */
  1794.     if (InUse[k]) break;
  1795.       
  1796.       /* remember that k+1 is the colorTable entry of k pixel (0 is transp.) */
  1797.       attribs->pixels[i-j] = k; /* k should be equal to 
  1798.                    PW->pixmap.colorTable[k+1]->pixel */
  1799.       attribs->colorTable[i] = (char **)XtCalloc(6, sizeof(char *));
  1800.       attribs->colorTable[i][0] = 
  1801.     XtNewString(PW->pixmap.colorTable[k + 1]->symbol);
  1802.       attribs->colorTable[i][1] = 
  1803.     XtNewString(PW->pixmap.colorTable[k + 1]->s_name);
  1804.       attribs->colorTable[i][2] = 
  1805.     XtNewString(PW->pixmap.colorTable[k + 1]->m_name);
  1806.       attribs->colorTable[i][3] = 
  1807.     XtNewString(PW->pixmap.colorTable[k + 1]->g4_name);
  1808.       attribs->colorTable[i][4] = 
  1809.     XtNewString(PW->pixmap.colorTable[k + 1]->g_name);
  1810.       attribs->colorTable[i][5] = 
  1811.     XtNewString(PW->pixmap.colorTable[k + 1]->c_name);
  1812.       k++;
  1813.     }
  1814.   
  1815.   /* fill in comments */
  1816.   attribs->hints_cmt = XtNewString(PW->pixmap.hints_cmt);
  1817.   attribs->colors_cmt = XtNewString(PW->pixmap.colors_cmt);
  1818.   attribs->pixels_cmt = XtNewString(PW->pixmap.pixels_cmt);
  1819.  
  1820.   /* free InUse array */
  1821.   XtFree(InUse);
  1822.   
  1823.   /* return struct */
  1824.   return(attribs);
  1825. }
  1826.  
  1827. #if NeedFunctionPrototypes
  1828. int PWWriteFile(Widget w, String filename)
  1829. #else
  1830. int PWWriteFile(w, filename)
  1831.     Widget w;
  1832.     String filename;
  1833. #endif
  1834. {
  1835.     PixmapWidget PW = (PixmapWidget) w;
  1836.     XImage *image, *mask_image;
  1837.     XPoint hot;
  1838.     int status;
  1839.     XpmAttributes *attribs;
  1840.     
  1841.     if (PW->pixmap.zooming) {
  1842.     image = CreatePixmapImage(PW,
  1843.                   (Dimension) PW->pixmap.zoom.image->width,
  1844.                   (Dimension) PW->pixmap.zoom.image->height);
  1845.     CopyImageData(PW->pixmap.zoom.image, image, 0, 0, 
  1846.               (Dimension) PW->pixmap.zoom.image->width,
  1847.               (Dimension) PW->pixmap.zoom.image->height, 0, 0);
  1848.     CopyImageData(PW->pixmap.image, image, 
  1849.               0, 0, 
  1850.               PW->pixmap.image->width - 1,
  1851.               PW->pixmap.image->height - 1,
  1852.               PW->pixmap.zoom.at_x, PW->pixmap.zoom.at_y);
  1853.  
  1854.     mask_image = CreateMaskImage(PW,
  1855.                      (Dimension)PW->pixmap.zoom.image->width,
  1856.                      (Dimension)PW->pixmap.zoom.image->height);
  1857.     CopyImageData(PW->pixmap.zoom.mask_image, mask_image, 0, 0, 
  1858.               (Dimension) PW->pixmap.zoom.mask_image->width,
  1859.               (Dimension) PW->pixmap.zoom.mask_image->height, 0, 0);
  1860.     CopyImageData(PW->pixmap.mask_image, mask_image, 
  1861.               0, 0, 
  1862.               PW->pixmap.mask_image->width - 1,
  1863.               PW->pixmap.mask_image->height - 1,
  1864.               PW->pixmap.zoom.at_x, PW->pixmap.zoom.at_y);
  1865.  
  1866.     if (QuerySet(PW->pixmap.hot.x, PW->pixmap.hot.y))
  1867.       {
  1868.         hot.x = PW->pixmap.hot.x + PW->pixmap.zoom.at_x;
  1869.         hot.y = PW->pixmap.hot.y + PW->pixmap.zoom.at_y;
  1870.       }
  1871.     else hot = PW->pixmap.zoom.hot;
  1872.     }
  1873.     else {
  1874.     image = PW->pixmap.image;
  1875.     mask_image = PW->pixmap.mask_image;
  1876.     hot = PW->pixmap.hot;
  1877.     }
  1878.     
  1879.     if (filename) 
  1880.       {
  1881.     XtFree(PW->pixmap.filename);
  1882.     PW->pixmap.filename = XtNewString(filename);
  1883.       }
  1884.  
  1885.     if (_PWDEBUG)
  1886.     fprintf(stderr, "Saving filename: %s\n", filename);
  1887.  
  1888.     attribs = fillXpmAttributesStruct(PW, image, mask_image);
  1889.     
  1890.     if (QuerySet(hot.x, hot.y))
  1891.       {
  1892.     attribs->valuemask |= XpmHotspot;
  1893.     attribs->x_hotspot = hot.x;
  1894.     attribs->y_hotspot = hot.y;
  1895.       }
  1896.     
  1897.     /* need to account for zooming for ports ?? */
  1898.     attribs->valuemask |= XpmExtensions;    /* save extensions */
  1899.     CopyExtensions( &attribs->extensions, &attribs->nextensions,
  1900.                     PW->pixmap.extensions, PW->pixmap.nextensions );
  1901.     
  1902.     if (attribs->mask_pixel) attribs->mask_pixel = 0; /* transparent color is
  1903.                              always first in 
  1904.                              colorTable */
  1905.     else attribs->mask_pixel = UNDEF_PIXEL;
  1906.  
  1907.     status = XpmWriteFileFromImage(dpy, PW->pixmap.filename, 
  1908.                    image, mask_image, attribs);
  1909.  
  1910.     XpmFreeAttributes(attribs);
  1911.     XtFree((char *)attribs);
  1912.     
  1913.     if (PW->pixmap.zooming) {
  1914.     DestroyPixmapImage(&image);
  1915.     DestroyMaskImage(&mask_image);
  1916.     }
  1917.         
  1918.     if (status == XpmSuccess)
  1919.       PW->pixmap.changed = False;
  1920.     
  1921.     return status;
  1922. }
  1923.  
  1924. #if NeedFunctionPrototypes
  1925. String PWGetFilename(Widget w, String *str)
  1926. #else
  1927. String PWGetFilename(w, str)
  1928.     Widget w;
  1929.     String *str;
  1930. #endif
  1931. {
  1932.     PixmapWidget PW = (PixmapWidget) w;
  1933.     
  1934.     *str = XtNewString(PW->pixmap.filename);
  1935.  
  1936.     return *str;
  1937. }
  1938.  
  1939. #if NeedFunctionPrototypes
  1940. String PWGetFilepath(Widget w, String *str)
  1941. #else
  1942. String PWGetFilepath(w, str)
  1943.     Widget w;
  1944.     String *str;
  1945. #endif
  1946. {
  1947.     PixmapWidget PW = (PixmapWidget) w;
  1948.     String end;
  1949.  
  1950.     *str = XtNewString(PW->pixmap.filename);
  1951.     end = rindex(*str, '/');
  1952.  
  1953.     if (end)
  1954.     *(end + 1) = '\0';
  1955.     else 
  1956.     **str = '\0';
  1957.  
  1958.     return *str;
  1959. }
  1960.  
  1961.  
  1962. void FixHotSpot(PW)
  1963.     PixmapWidget PW;
  1964. {
  1965.     if (!QueryInPixmap(PW, PW->pixmap.hot.x, PW->pixmap.hot.y))
  1966.     PW->pixmap.hot.x = PW->pixmap.hot.y = NotSet;
  1967. }
  1968.  
  1969.  
  1970. void ZoomOut(PW)
  1971.     PixmapWidget PW;
  1972. {
  1973.     CopyImageData(PW->pixmap.image, PW->pixmap.zoom.image, 
  1974.           0, 0, 
  1975.           PW->pixmap.image->width - 1,
  1976.           PW->pixmap.image->height - 1,
  1977.           PW->pixmap.zoom.at_x, PW->pixmap.zoom.at_y);
  1978.     
  1979.     CopyImageData(PW->pixmap.mask_image, PW->pixmap.zoom.mask_image, 
  1980.           0, 0, 
  1981.           PW->pixmap.mask_image->width - 1,
  1982.           PW->pixmap.mask_image->height - 1,
  1983.           PW->pixmap.zoom.at_x, PW->pixmap.zoom.at_y);
  1984.  
  1985.     DestroyPixmapImage(&PW->pixmap.image);
  1986.     DestroyPixmapImage(&PW->pixmap.buffer);
  1987.     DestroyMaskImage(&PW->pixmap.mask_image);
  1988.     DestroyMaskImage(&PW->pixmap.mask_buffer);
  1989.     
  1990.     PW->pixmap.image = PW->pixmap.zoom.image;
  1991.     PW->pixmap.mask_image = PW->pixmap.zoom.mask_image;
  1992.     PW->pixmap.buffer = PW->pixmap.zoom.buffer;
  1993.     PW->pixmap.mask_buffer = PW->pixmap.zoom.mask_buffer;
  1994.     PW->pixmap.width = PW->pixmap.image->width;
  1995.     PW->pixmap.height = PW->pixmap.image->height;
  1996.     PW->pixmap.fold = PW->pixmap.zoom.fold;
  1997.     PW->pixmap.changed |= PW->pixmap.zoom.changed;
  1998.     PW->pixmap.grid = PW->pixmap.zoom.grid;
  1999.  
  2000.     if (QuerySet(PW->pixmap.hot.x, PW->pixmap.hot.y)) {
  2001.     PW->pixmap.hot.x += PW->pixmap.zoom.at_x;
  2002.     PW->pixmap.hot.y += PW->pixmap.zoom.at_y;
  2003.     }
  2004.     else
  2005.     PW->pixmap.hot = PW->pixmap.zoom.hot;
  2006.  
  2007.     PW->pixmap.mark.from_x = NotSet;
  2008.     PW->pixmap.mark.from_y = NotSet;
  2009.     PW->pixmap.mark.to_x = NotSet;
  2010.     PW->pixmap.mark.to_y = NotSet;
  2011.     PW->pixmap.zooming = False;
  2012. }    
  2013.  
  2014. #if NeedFunctionPrototypes
  2015. void PWZoomOut(Widget w)
  2016. #else
  2017. void PWZoomOut(w)
  2018.     Widget w;
  2019. #endif
  2020. {
  2021.     PixmapWidget PW = (PixmapWidget) w;
  2022.     
  2023.     if (PW->pixmap.zooming) {
  2024.     ZoomOut(PW);
  2025.     
  2026.     InternalResize(PW);
  2027.     if (PW->core.visible)
  2028.         XClearArea(dpy, XtWindow(PW),
  2029.                0, 0, 
  2030.                PW->core.width, PW->core.height,
  2031.                True);
  2032.     }
  2033. }
  2034.  
  2035. #if NeedFunctionPrototypes
  2036. void PWZoomMarked(Widget w)
  2037. #else
  2038. void PWZoomMarked(w)
  2039.     Widget w;
  2040. #endif
  2041. {
  2042.     PixmapWidget PW = (PixmapWidget) w;
  2043.  
  2044.     PWZoomIn(w, 
  2045.          PW->pixmap.mark.from_x, PW->pixmap.mark.from_y,
  2046.          PW->pixmap.mark.to_x,   PW->pixmap.mark.to_y);
  2047. }
  2048.  
  2049. #if NeedFunctionPrototypes
  2050. void PWZoomIn(Widget w, Position from_x, Position from_y, 
  2051.           Position to_x, Position to_y)
  2052. #else
  2053. void PWZoomIn(w, from_x, from_y, to_x, to_y)
  2054.     Widget w;
  2055.     Position from_x, from_y, to_x, to_y;
  2056. #endif
  2057. {
  2058.     PixmapWidget PW = (PixmapWidget) w;
  2059.     XImage *image, *buffer, *mask_image, *mask_buffer;    
  2060.     Dimension width, height, coreWidth, coreHeight;
  2061.   
  2062.     if (PW->pixmap.zooming)
  2063.     PWZoomOut(w);
  2064.     
  2065.     QuerySwap(from_x, to_x);
  2066.     QuerySwap(from_y, to_y);
  2067.     from_x = max(0, from_x);
  2068.     from_y = max(0, from_y);
  2069.     to_x = min(PW->pixmap.width - 1, to_x);
  2070.     to_y = min(PW->pixmap.height - 1, to_y);
  2071.     
  2072.     width = to_x - from_x + 1;
  2073.     height = to_y - from_y + 1;
  2074.  
  2075.     image = CreatePixmapImage(PW, width, height);
  2076.     buffer = CreatePixmapImage(PW, width, height);
  2077.     mask_image = CreateMaskImage(PW, width, height);
  2078.     mask_buffer = CreateMaskImage(PW, width, height);
  2079.  
  2080.     CopyImageData(PW->pixmap.image, image, from_x, from_y, to_x, to_y, 0, 0);
  2081.     CopyImageData(PW->pixmap.buffer, buffer, from_x, from_y, to_x, to_y, 0, 0);
  2082.     CopyImageData(PW->pixmap.mask_image, mask_image,
  2083.           from_x, from_y, to_x, to_y, 0, 0);
  2084.     CopyImageData(PW->pixmap.mask_buffer, mask_buffer,
  2085.           from_x, from_y, to_x, to_y, 0, 0);
  2086.     
  2087.     PW->pixmap.zoom.image = PW->pixmap.image;
  2088.     PW->pixmap.zoom.buffer = PW->pixmap.buffer;
  2089.     PW->pixmap.zoom.mask_image = PW->pixmap.mask_image;
  2090.     PW->pixmap.zoom.mask_buffer = PW->pixmap.mask_buffer;
  2091.     PW->pixmap.zoom.at_x = from_x;
  2092.     PW->pixmap.zoom.at_y = from_y;
  2093.     PW->pixmap.zoom.fold = PW->pixmap.fold;
  2094.     PW->pixmap.zoom.changed = PW->pixmap.changed;
  2095.     PW->pixmap.zoom.hot = PW->pixmap.hot;
  2096.     PW->pixmap.zoom.grid = PW->pixmap.grid;
  2097.  
  2098.     PW->pixmap.image = image;
  2099.     PW->pixmap.buffer = buffer;
  2100.     PW->pixmap.mask_image = mask_image;
  2101.     PW->pixmap.mask_buffer = mask_buffer;
  2102.     PW->pixmap.width = width;
  2103.     PW->pixmap.height = height;
  2104.     PW->pixmap.changed = False;
  2105.     PW->pixmap.hot.x -= from_x;
  2106.     PW->pixmap.hot.y -= from_y;
  2107.     PW->pixmap.mark.from_x = NotSet;
  2108.     PW->pixmap.mark.from_y = NotSet;
  2109.     PW->pixmap.mark.to_x = NotSet;
  2110.     PW->pixmap.mark.to_y = NotSet;
  2111.     PW->pixmap.zooming = True;
  2112.     PW->pixmap.grid = True; /* potencially true, could use a resource here */
  2113.  
  2114.     FixHotSpot(PW);
  2115.  
  2116.     coreWidth = PW->core.width;
  2117.     coreHeight = PW->core.height;
  2118.     InternalResize(PW);
  2119.     if (PW->core.visible)
  2120.     XClearArea(dpy, XtWindow(PW),
  2121.            0, 0, 
  2122.            coreWidth, coreHeight,
  2123.            True);
  2124. }
  2125.  
  2126. XImage *ScalePixmapImage();
  2127.  
  2128. #if NeedFunctionPrototypes
  2129. void PWRescale(Widget w, Dimension width, Dimension height)
  2130. #else
  2131. void PWRescale(w, width, height)
  2132.     Widget w;
  2133.     Dimension width, height;
  2134. #endif
  2135. {
  2136.     PixmapWidget PW = (PixmapWidget) w;
  2137.     XImage *image, *mask_image, *buffer, *mask_buffer;
  2138.  
  2139.     if (PW->pixmap.zooming)
  2140.     ZoomOut(PW);
  2141.         
  2142.     image = ScalePixmapImage(PW, PW->pixmap.image, 
  2143.                (double) width / (double) PW->pixmap.image->width,
  2144.                (double) height / (double) PW->pixmap.image->height);
  2145.     mask_image = ScaleMaskImage(PW, PW->pixmap.mask_image, 
  2146.              (double) width / (double) PW->pixmap.mask_image->width,
  2147.              (double) height / (double) PW->pixmap.mask_image->height);
  2148.  
  2149.     DestroyPixmapImage(&PW->pixmap.image);
  2150.     DestroyMaskImage(&PW->pixmap.mask_image);
  2151.     
  2152.     PW->pixmap.image = image;
  2153.     PW->pixmap.mask_image = mask_image;
  2154.     PW->pixmap.width = image->width;
  2155.     PW->pixmap.height = image->height;
  2156.     
  2157.     FixHotSpot(PW);
  2158.     FixMark(PW);
  2159.  
  2160.     InternalResize(PW);
  2161.     if (PW->core.visible)
  2162.     XClearArea(dpy, XtWindow(PW),
  2163.            0, 0, 
  2164.            PW->core.width, PW->core.height,
  2165.            True);
  2166. }
  2167.  
  2168. #if NeedFunctionPrototypes
  2169. Boolean PWQueryZooming(Widget w)
  2170. #else
  2171. Boolean PWQueryZooming(w)
  2172.     Widget w;
  2173. #endif
  2174. {
  2175.     PixmapWidget PW = (PixmapWidget) w;
  2176.  
  2177.     return PW->pixmap.zooming;
  2178. }
  2179.  
  2180. #if NeedFunctionPrototypes
  2181. void PWResize(Widget w, Dimension width, Dimension height)
  2182. #else
  2183. void PWResize(w, width, height)
  2184.     Widget w;
  2185.     Dimension width, height;
  2186. #endif
  2187. {
  2188.     PixmapWidget PW = (PixmapWidget) w;
  2189.     XImage *image, *mask_image, *buffer, *mask_buffer;
  2190.  
  2191.     if (PW->pixmap.zooming)
  2192.     ZoomOut(PW);
  2193.  
  2194.     image = CreatePixmapImage(PW, width, height);
  2195.     mask_image = CreateMaskImage(PW, width, height);
  2196.  
  2197.     TransferImageData(PW->pixmap.image, image);
  2198.     TransferImageData(PW->pixmap.mask_image, mask_image);
  2199.     
  2200.     DestroyPixmapImage(&PW->pixmap.image);
  2201.     DestroyMaskImage(&PW->pixmap.mask_image);
  2202.  
  2203.     PW->pixmap.image = image;
  2204.     PW->pixmap.mask_image = mask_image;
  2205.     PW->pixmap.width = width;
  2206.     PW->pixmap.height = height;
  2207.  
  2208.     FixHotSpot(PW);
  2209.     FixMark(PW);
  2210.  
  2211.     InternalResize(PW);
  2212.     if (PW->core.visible)
  2213.     XClearArea(dpy, XtWindow(PW),
  2214.            0, 0, 
  2215.            PW->core.width, PW->core.height,
  2216.            True);
  2217. }
  2218.  
  2219. static void Destroy(w)
  2220.     Widget w;
  2221. {
  2222.     PixmapWidget PW = (PixmapWidget) w;
  2223.     int i;
  2224.     
  2225.     /* free colorTable */
  2226.     for (i = 0; i < 1<<depth; i++)
  2227.       if (PW->pixmap.colorTable[i])
  2228.     {
  2229.       if (PW->pixmap.colorTable[i]->symbol) 
  2230.         XtFree(PW->pixmap.colorTable[i]->symbol);
  2231.       if (PW->pixmap.colorTable[i]->s_name) 
  2232.         XtFree(PW->pixmap.colorTable[i]->s_name);
  2233.       if (PW->pixmap.colorTable[i]->m_name) 
  2234.         XtFree(PW->pixmap.colorTable[i]->m_name);
  2235.       if (PW->pixmap.colorTable[i]->g4_name) 
  2236.         XtFree(PW->pixmap.colorTable[i]->g4_name);
  2237.       if (PW->pixmap.colorTable[i]->g_name) 
  2238.         XtFree(PW->pixmap.colorTable[i]->g_name);
  2239.       if (PW->pixmap.colorTable[i]->c_name) 
  2240.         XtFree(PW->pixmap.colorTable[i]->c_name);
  2241.       XtFree((char *)PW->pixmap.colorTable[i]);
  2242.     }
  2243.     XtFree((char *)PW->pixmap.colorTable);
  2244.  
  2245.     XFreeGC(dpy, PW->pixmap.drawing_gc);
  2246.     XFreeGC(dpy, PW->pixmap.highlighting_gc);
  2247.     XFreeGC(dpy, PW->pixmap.framing_gc);
  2248.     XFreeGC(dpy, PW->pixmap.transparent_gc);
  2249.  
  2250.     DestroyPixmapImage(&PW->pixmap.image);
  2251.     DestroyPixmapImage(&PW->pixmap.buffer);
  2252.     DestroyMaskImage(&PW->pixmap.mask_image);
  2253.     DestroyMaskImage(&PW->pixmap.mask_buffer);
  2254.     
  2255.     PWRemoveAllRequests(w);
  2256. }
  2257.  
  2258.  
  2259. /* internal function that makes a gemotry request to PixmapWidget's parent */
  2260. static void InternalResize(PW)
  2261.      PixmapWidget PW;
  2262. {
  2263.     Dimension w, h, rw, rh;
  2264.     XtGeometryResult status;
  2265.  
  2266.     w = 2 * (int)PW->pixmap.distance +
  2267.       (int)PW->pixmap.width * PW->pixmap.squareW;
  2268.     h = 2 * (int)PW->pixmap.distance +
  2269.       (int)PW->pixmap.height * PW->pixmap.squareH;
  2270.     status = XtMakeResizeRequest((Widget)PW, w, h, &rw, &rh);
  2271.  
  2272.     if (status == XtGeometryAlmost)
  2273.       status = XtMakeResizeRequest((Widget)PW, rw, rh, NULL, NULL);
  2274.     else if (status == XtGeometryNo)
  2275.       XtWarning("PixmapWidget: Geometry request denied");
  2276. }
  2277.  
  2278.  
  2279. static void Resize(PW)
  2280.      PixmapWidget PW;
  2281. {
  2282.     Dimension squareW, squareH;
  2283.  
  2284.     if (PW->pixmap.resize == True)
  2285.       {
  2286.     squareW = max(1, 
  2287.               ((int)PW->core.width - 2 * (int)PW->pixmap.distance) / 
  2288.               (int)PW->pixmap.width);
  2289.     squareH = max(1, 
  2290.               ((int)PW->core.height - 2 * (int)PW->pixmap.distance) / 
  2291.               (int)PW->pixmap.height);
  2292.  
  2293.     if (PW->pixmap.proportional)
  2294.       PW->pixmap.squareW = PW->pixmap.squareH = min(squareW, squareH);
  2295.     else {
  2296.       PW->pixmap.squareW = squareW;
  2297.       PW->pixmap.squareH = squareH;
  2298.     }
  2299.       }
  2300.  
  2301.     PW->pixmap.horizOffset = max((Position)PW->pixmap.distance, 
  2302.                  (Position)(PW->core.width - 
  2303.                         PW->pixmap.width * 
  2304.                         PW->pixmap.squareW) / 2);
  2305.     PW->pixmap.vertOffset = max((Position)PW->pixmap.distance, 
  2306.                 (Position)(PW->core.height - 
  2307.                        PW->pixmap.height * 
  2308.                        PW->pixmap.squareH) / 2);
  2309.  
  2310.     PW->pixmap.grid &= ((PW->pixmap.squareW > PW->pixmap.grid_tolerance) && 
  2311.             (PW->pixmap.squareH > PW->pixmap.grid_tolerance));
  2312. }
  2313.  
  2314. static void Redisplay(PW, event, region)
  2315.      PixmapWidget PW;
  2316.      XEvent      *event;
  2317.      Region       region;
  2318. {
  2319.     if(event->type == Expose) {
  2320.     if (PW->core.visible) {  
  2321.         Refresh(PW, 
  2322.             event->xexpose.x, event->xexpose.y,
  2323.             event->xexpose.width, event->xexpose.height);
  2324.     }
  2325.     }
  2326. }
  2327.  
  2328. #if NeedFunctionPrototypes
  2329. void PWClip(Widget w, Position from_x, Position from_y, 
  2330.         Position to_x, Position to_y)
  2331. #else
  2332. void PWClip(w, from_x, from_y, to_x, to_y)
  2333.     Widget w;
  2334.     Position from_x, from_y, to_x, to_y;
  2335. #endif
  2336. {
  2337.     PixmapWidget PW = (PixmapWidget) w;
  2338.     XRectangle rectangle;
  2339.   
  2340.     QuerySwap(from_x, to_x);
  2341.     QuerySwap(from_y, to_y);
  2342.     from_x = max(0, from_x);
  2343.     from_y = max(0, from_y);
  2344.     to_x = min(PW->pixmap.width - 1, to_x);
  2345.     to_y = min(PW->pixmap.height - 1, to_y);
  2346.  
  2347.     rectangle.x = InWindowX(PW, from_x);
  2348.     rectangle.y = InWindowY(PW, from_y);
  2349.     rectangle.width = InWindowX(PW, to_x  + 1) - InWindowX(PW, from_x);
  2350.     rectangle.height = InWindowY(PW, to_y + 1) - InWindowY(PW, from_y);
  2351.     XSetClipRectangles(dpy,
  2352.                PW->pixmap.highlighting_gc,
  2353.                0, 0,
  2354.                &rectangle, 1,
  2355.                Unsorted);
  2356.     XSetClipRectangles(dpy,
  2357.                PW->pixmap.drawing_gc,
  2358.                0, 0,
  2359.                &rectangle, 1,
  2360.                Unsorted);
  2361.     XSetClipRectangles(dpy,
  2362.                PW->pixmap.framing_gc,
  2363.                0, 0,
  2364.                &rectangle, 1,
  2365.                Unsorted);
  2366. }
  2367.  
  2368. #if NeedFunctionPrototypes
  2369. void PWUnclip(Widget w)
  2370. #else
  2371. void PWUnclip(w)
  2372.     Widget w;
  2373. #endif
  2374. {
  2375.     PixmapWidget PW = (PixmapWidget) w;
  2376.     XRectangle rectangle;
  2377.   
  2378.     rectangle.x = InWindowX(PW, 0);
  2379.     rectangle.y = InWindowY(PW, 0);
  2380.     rectangle.width = InWindowX(PW, PW->pixmap.width) - InWindowX(PW, 0);
  2381.     rectangle.height = InWindowY(PW, PW->pixmap.height) - InWindowY(PW, 0);
  2382.     XSetClipRectangles(dpy,
  2383.                PW->pixmap.highlighting_gc,
  2384.                0, 0,
  2385.                &rectangle, 1,
  2386.                Unsorted);
  2387.     XSetClipRectangles(dpy,
  2388.                PW->pixmap.drawing_gc,
  2389.                0, 0,
  2390.                &rectangle, 1,
  2391.                Unsorted);
  2392.     XSetClipRectangles(dpy,
  2393.                PW->pixmap.framing_gc,
  2394.                0, 0,
  2395.                &rectangle, 1,
  2396.                Unsorted);
  2397. }
  2398.  
  2399. void Refresh(PW, x, y, width, height)
  2400.     PixmapWidget PW;
  2401.     Position     x, y;
  2402.     Dimension    width, height;
  2403. {
  2404.     XRectangle rectangle;
  2405.     Position i, j;
  2406.  
  2407.     XDefineCursor(dpy, XtWindow(PW), PW->pixmap.cursor);
  2408.  
  2409.     rectangle.x = min(x, InWindowX(PW, InPixmapX(PW, x)));
  2410.     rectangle.y = min(y, InWindowY(PW, InPixmapY(PW, y)));
  2411.     rectangle.width = max(x + width,
  2412.              InWindowX(PW, InPixmapX(PW, x + width)+1)) - rectangle.x;
  2413.     rectangle.height = max(y + height,
  2414.              InWindowY(PW, InPixmapY(PW, y + height)+1)) - rectangle.y;
  2415.     
  2416.     XClearArea(dpy, XtWindow(PW),
  2417.            rectangle.x, rectangle.y,
  2418.            rectangle.width, rectangle.height,
  2419.            False);
  2420.  
  2421.     XSetClipRectangles(dpy,
  2422.                PW->pixmap.framing_gc,
  2423.                0, 0,
  2424.                &rectangle, 1,
  2425.                Unsorted);
  2426.  
  2427.     XDrawRectangle(dpy, XtWindow(PW),
  2428.            PW->pixmap.framing_gc,
  2429.            InWindowX(PW, 0) - 1, InWindowY(PW, 0) - 1,
  2430.            InWindowX(PW, PW->pixmap.width) - InWindowX(PW, 0) + 1, 
  2431.            InWindowY(PW, PW->pixmap.height) - InWindowY(PW, 0) + 1);
  2432.  
  2433.     PWClip((Widget) PW,
  2434.        InPixmapX(PW, x),InPixmapY(PW, y),
  2435.        InPixmapX(PW, x + width), InPixmapY(PW, y + height));
  2436.  
  2437.     PWRedrawSquares((Widget) PW, InPixmapX(PW, x), InPixmapY(PW, y),
  2438.             InPixmapX(PW, x + width), InPixmapY(PW, y + height));
  2439.     
  2440.     PWRedrawGrid((Widget) PW,
  2441.          InPixmapX(PW, x), InPixmapY(PW, y),
  2442.          InPixmapX(PW, x + width), InPixmapY(PW, y + height));
  2443.     PWRedrawMark((Widget) PW);
  2444.     PWRedrawHotSpot((Widget) PW);
  2445.     if (PW->pixmap.redrawCallback)
  2446.         PW->pixmap.redrawCallback( (Widget) PW, Set );    /* redraw extensions */
  2447.     PWRedrawAxes((Widget) PW);
  2448.     PWUnclip((Widget) PW);
  2449. }
  2450.  
  2451. #if NeedFunctionPrototypes
  2452. void PWSwitchGrid(Widget w)
  2453. #else
  2454. void PWSwitchGrid(w)
  2455.     Widget w;
  2456. #endif
  2457. {
  2458.     PixmapWidget PW = (PixmapWidget) w;
  2459.     PW->pixmap.grid ^= TRUE;
  2460.     PWDrawGrid(w,
  2461.            0, 0,
  2462.            PW->pixmap.image->width - 1, PW->pixmap.image->height - 1);
  2463. }
  2464.  
  2465. #if NeedFunctionPrototypes
  2466. void PWGrid(Widget w, Boolean _switch)
  2467. #else
  2468. void PWGrid(w, _switch)
  2469.     Widget w;
  2470.     Boolean _switch;
  2471. #endif
  2472. {
  2473.     PixmapWidget PW = (PixmapWidget) w;
  2474.     
  2475.     if (PW->pixmap.grid != _switch)
  2476.     PWSwitchGrid(w);
  2477. }
  2478.  
  2479. static Boolean SetValues(current, request, new)
  2480.      Widget current, request, new;
  2481. {
  2482.   PixmapWidget p_old = (PixmapWidget) current;
  2483.   PixmapWidget p_new = (PixmapWidget) new;
  2484.   PixmapWidget p_req = (PixmapWidget) request;
  2485.   
  2486.   if ((p_old->pixmap.cursor != p_req->pixmap.cursor) && XtIsRealized(new))
  2487.     XDefineCursor(XtDisplay(new), XtWindow(new), p_new->pixmap.cursor);
  2488.   if (p_old->pixmap.squareW != p_req->pixmap.squareW)
  2489.     {
  2490.     if ((p_old->pixmap.proportional == True) &&
  2491.         (p_new->pixmap.squareH != p_new->pixmap.squareW))
  2492.         p_new->pixmap.squareH = p_new->pixmap.squareW;
  2493.     InternalResize(p_new);
  2494.     }
  2495.   
  2496.   if (p_old->pixmap.squareH != p_req->pixmap.squareH)
  2497.     {
  2498.     if ((p_old->pixmap.proportional == True) &&
  2499.         (p_new->pixmap.squareH != p_new->pixmap.squareW))
  2500.         p_new->pixmap.squareW = p_new->pixmap.squareH;
  2501.     InternalResize(p_new);
  2502.     }
  2503.   
  2504.     return FALSE;
  2505. }
  2506.  
  2507. #if NeedFunctionPrototypes
  2508. Boolean PWQueryProportional(Widget w)
  2509. #else
  2510. Boolean PWQueryProportional(w)
  2511.     Widget w;
  2512. #endif
  2513. {
  2514.     PixmapWidget PW = (PixmapWidget) w;
  2515.  
  2516.     return (PW->pixmap.proportional);
  2517. }
  2518.  
  2519. #if NeedFunctionPrototypes
  2520. void PWSwitchProportional(Widget w)
  2521. #else
  2522. void PWSwitchProportional(w)
  2523.     Widget w;
  2524. #endif
  2525. {
  2526.     PixmapWidget PW = (PixmapWidget) w;
  2527.  
  2528.     PW->pixmap.proportional ^= True;
  2529.  
  2530.     InternalResize(PW);
  2531.     if (PW->core.visible)
  2532.     XClearArea(dpy, XtWindow(PW),
  2533.            0, 0, 
  2534.            PW->core.width, PW->core.height,
  2535.            True);
  2536. }
  2537.  
  2538. #if NeedFunctionPrototypes
  2539. void PWProportional(Widget w, Boolean _switch)
  2540. #else
  2541. void PWProportional(w, _switch)
  2542.     Widget w;
  2543.     Boolean _switch;
  2544. #endif
  2545. {
  2546.     PixmapWidget PW = (PixmapWidget) w;
  2547.  
  2548.     if (PW->pixmap.proportional != _switch)
  2549.     PWSwitchProportional(w);
  2550. }
  2551.  
  2552.  
  2553. #if NeedFunctionPrototypes
  2554. void PWSetPickPixelDrawProc( Widget w, PickPixelProc proc )
  2555. #else
  2556. void PWSetPickPixelDrawProc( w, proc )
  2557.      Widget        w;
  2558.      PickPixelProc    proc;
  2559. #endif
  2560. {
  2561.   PixmapWidget PW = (PixmapWidget) w;
  2562.   
  2563.   PW->pixmap.pickPixelDraw = proc;
  2564. }
  2565.  
  2566.  
  2567. #if NeedFunctionPrototypes
  2568. void PWSetPickPixelCompleteProc( Widget w, PickPixelProc proc )
  2569. #else
  2570. void PWSetPickPixelCompleteProc( w, proc )
  2571.      Widget        w;
  2572.      PickPixelProc    proc;
  2573. #endif
  2574. {
  2575.   PixmapWidget PW = (PixmapWidget) w;
  2576.   
  2577.   PW->pixmap.pickPixelComplete = proc;
  2578. }
  2579.  
  2580.  
  2581. #if NeedFunctionPrototypes
  2582. void PWSetDrawPointProc( Widget w, PWDrawPointProc proc )
  2583. #else
  2584. void PWSetDrawPointProc( w, proc )
  2585.      Widget        w;
  2586.      PWDrawPointProc    proc;
  2587. #endif
  2588. {
  2589.   PixmapWidget PW = (PixmapWidget) w;
  2590.  
  2591.   PW->pixmap.drawPointCallback = proc;
  2592. }
  2593.  
  2594.  
  2595. #if NeedFunctionPrototypes
  2596. void PWSetRedrawProc( Widget w, PWRedrawProc proc )
  2597. #else
  2598. void PWSetRedrawProc( w, proc )
  2599.      Widget        w;
  2600.      PWRedrawProc    proc;
  2601. #endif
  2602. {
  2603.   PixmapWidget PW = (PixmapWidget) w;
  2604.  
  2605.   PW->pixmap.redrawCallback = proc;
  2606. }
  2607.  
  2608.  
  2609. #if NeedFunctionPrototypes
  2610. void PWSetTranslateProc( Widget w, PWTranslateProc proc )
  2611. #else
  2612. void PWSetTranslateProc( w, proc )
  2613.      Widget        w;
  2614.      PWTranslateProc    proc;
  2615. #endif
  2616. {
  2617.   PixmapWidget PW = (PixmapWidget) w;
  2618.  
  2619.   PW->pixmap.translateCallback = proc;
  2620. }
  2621.  
  2622.  
  2623. #if NeedFunctionPrototypes
  2624. void PWSetRotateProc( Widget w, PWRotateProc proc )
  2625. #else
  2626. void PWSetRotateProc( w, proc )
  2627.      Widget        w;
  2628.      PWRotateProc    proc;
  2629. #endif
  2630. {
  2631.   PixmapWidget PW = (PixmapWidget) w;
  2632.   
  2633.   PW->pixmap.rotateCallback = proc;
  2634. }
  2635.  
  2636.  
  2637. #if NeedFunctionPrototypes
  2638. void PWSetFlipProc( Widget w, PWFlipProc proc )
  2639. #else
  2640. void PWSetFlipProc( w, proc )
  2641.      Widget        w;
  2642.      PWFlipProc    proc;
  2643. #endif
  2644. {
  2645.   PixmapWidget PW = (PixmapWidget) w;
  2646.  
  2647.   PW->pixmap.flipCallback = proc;
  2648. }
  2649.  
  2650.  
  2651. #if NeedFunctionPrototypes
  2652. void PWSetFont( Widget w, XFontStruct *font_struct ) 
  2653. #else
  2654. void PWSetFont( w, font_struct ) 
  2655.      Widget     w; 
  2656.      XFontStruct *font_struct; 
  2657. #endif
  2658. {
  2659.   PixmapWidget PW = (PixmapWidget) w;
  2660.  
  2661.   PW->pixmap.font_struct = font_struct;
  2662.  
  2663.   if ( PW->pixmap.font_struct && PW->pixmap.text_string ) {
  2664.  
  2665.       int          direction, ascent, descent;
  2666.       XCharStruct  size;
  2667.  
  2668.       XTextExtents( PW->pixmap.font_struct, 
  2669.                     PW->pixmap.text_string, strlen(PW->pixmap.text_string), 
  2670.                     &direction, &ascent, &descent, &size );
  2671.  
  2672.       PW->pixmap.text_rbearing = size.rbearing;
  2673.       PW->pixmap.text_lbearing = size.lbearing;
  2674.       PW->pixmap.text_ascent   = size.ascent;
  2675.       PW->pixmap.text_descent  = size.descent;
  2676.   }
  2677. }
  2678.  
  2679.  
  2680. #if NeedFunctionPrototypes
  2681. void PWSetText( Widget w, String s ) 
  2682. #else
  2683. void PWSetText( w, s ) 
  2684.      Widget    w; 
  2685.      String    s; 
  2686. #endif
  2687. {
  2688.   PixmapWidget PW = (PixmapWidget) w;
  2689.  
  2690.   PW->pixmap.text_string = XtNewString( s );
  2691.  
  2692.   if ( PW->pixmap.font_struct && PW->pixmap.text_string ) {
  2693.  
  2694.       int          direction, ascent, descent;
  2695.       XCharStruct  size;
  2696.  
  2697.       XTextExtents( PW->pixmap.font_struct, 
  2698.                     PW->pixmap.text_string, strlen(PW->pixmap.text_string), 
  2699.                     &direction, &ascent, &descent, &size );
  2700.  
  2701.       PW->pixmap.text_rbearing = size.rbearing;
  2702.       PW->pixmap.text_lbearing = size.lbearing;
  2703.       PW->pixmap.text_ascent   = size.ascent;
  2704.       PW->pixmap.text_descent  = size.descent;
  2705.   }
  2706. }
  2707.  
  2708.  
  2709.  
  2710.